From c6758e5e205ae94c71afc097fb3d6425fdf079de Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Mon, 5 Oct 2026 01:35:46 +0800 Subject: [PATCH] =?UTF-8?q?style(=E6=B8=B8=E6=88=8F=E5=85=B1=E5=88=9B):=20?= =?UTF-8?q?=E6=8C=89=20rustfmt=20=E4=BF=AE=E6=AD=A3=E6=9C=AC=E5=88=86?= =?UTF-8?q?=E6=94=AF=E6=96=B0=E5=A2=9E=E4=BB=A3=E7=A0=81=E7=9A=84=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=EF=BC=88=E6=97=A0=E8=AF=AD=E4=B9=89=E5=8F=98=E5=8C=96?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 判定依据(先判定再动手):仓库根 `rustfmt.toml`(edition 2024 / max_width 100 / use_small_heuristics=Default)与本地 rustfmt 1.9.0-stable 一致;`cargo fmt --all --manifest-path server-rs/Cargo.toml -- --check` 的红项(24 处 hunk / 7 个文件)**全部落在本分支新增的代码上**,且 master 版本的同名文件在同样配置下是干净的(`git show 6c9566058:...errors.rs` 单文件 --check 通过),另三个 workspace(tauri / unity / godot)也 CLEAN。因此是本分支引入的格式漂移,不是环境差异——仓库 `npm run check:rustfmt`(在 `npm run lint` 里)会因此失败,故修正。 - api-server/src/modules/game_distribution.rs:两处 import 列表按宽度重排;`derived_games_payload` / `lineage_tree_payload` / `set_game_distribution_fork_authorization` 调用与 `fork_source_target` 的 `Err(...)`、取件相关测试的换行与尾逗号 - spacetime-module/src/game_distribution.rs:3 处 `return Err(...)` 与 `let Some(game) = ctx.db...` 的换行 - spacetime-client:`active.rs` 的 import 列表、`mapper/game_distribution.rs` 的 `collect()` 链、`game_distribution.rs` 的 procedure 回调换行 - module-game-distribution:`domain.rs` 的错误码字面量元组、`errors.rs` `Display` 分支的换行 验证:`cargo fmt --all --manifest-path server-rs/Cargo.toml -- --check` 退出 0;逐文件比对「删除全部空白后」的字符流,差异仅为 rustfmt 展开/折叠时增删的**尾逗号**(每文件长度差 ≤4 字符),无语义变化;格式化后 `cargo check --all-targets` 与 `cargo test -p api-server game_distribution`(52 passed)仍通过。 --- .../src/modules/game_distribution.rs | 122 ++++++++---------- .../module-game-distribution/src/domain.rs | 5 +- .../module-game-distribution/src/errors.rs | 10 +- .../crates/spacetime-client/src/active.rs | 5 +- .../src/active/mapper/game_distribution.rs | 6 +- .../spacetime-client/src/game_distribution.rs | 15 ++- .../spacetime-module/src/game_distribution.rs | 22 ++-- 7 files changed, 86 insertions(+), 99 deletions(-) diff --git a/server-rs/crates/api-server/src/modules/game_distribution.rs b/server-rs/crates/api-server/src/modules/game_distribution.rs index ba86c6bee..e5b6a2fb3 100644 --- a/server-rs/crates/api-server/src/modules/game_distribution.rs +++ b/server-rs/crates/api-server/src/modules/game_distribution.rs @@ -40,10 +40,9 @@ use shared_contracts::game_distribution::{ GAME_DISTRIBUTION_CATEGORIES, GAME_DISTRIBUTION_VERSION_NUMBER_CONFLICT, GameDistributionAuthor, GameDistributionCreateGameRequest, GameDistributionCreateVersionRequest, GameDistributionDerivedResponse, - GameDistributionForkAuthorization, GameDistributionForkSource, - GameDistributionForkSourceKind, GameDistributionForkSourceResponse, - GameDistributionInputMode, GameDistributionLineageNode, GameDistributionLineageResponse, - GameDistributionMyReviewResponse, GameDistributionOrientation, + GameDistributionForkAuthorization, GameDistributionForkSource, GameDistributionForkSourceKind, + GameDistributionForkSourceResponse, GameDistributionInputMode, GameDistributionLineageNode, + GameDistributionLineageResponse, GameDistributionMyReviewResponse, GameDistributionOrientation, GameDistributionPublishMetadataSuggestion, GameDistributionPublishMetadataSuggestionRequest, GameDistributionRatingSummary, GameDistributionReview, GameDistributionReviewsResponse, GameDistributionSaveReviewRequest, GameDistributionSaveReviewResponse, @@ -57,16 +56,15 @@ use spacetime_client::{ GameDistributionCancelVersionRecordInput, GameDistributionDeleteGameRecordInput, GameDistributionDerivedGamesRecord, GameDistributionForkSourceRecord, GameDistributionGameRecord, GameDistributionGetGameRecordInput, - GameDistributionLineageNodeRecord, - GameDistributionLineageTreeRecord, GameDistributionOwnerGameRecord, - GameDistributionPublicGameListRecordInput, GameDistributionPublicGameRecord, - GameDistributionRatingSummaryRecord, GameDistributionRejectRecordInput, - GameDistributionRestoreRecordInput, GameDistributionReviewGameListRecordInput, - GameDistributionReviewModerationOperationRecord, GameDistributionReviewModerationRecordInput, - GameDistributionSetForkAuthorizationRecordInput, GameDistributionSubmitReviewRecordInput, - GameDistributionSuspendRecordInput, GameDistributionUnpublishRecordInput, - GameDistributionUpdateMetadataRecordInput, GameDistributionUserReviewRecord, - GameDistributionVersionRecord, SpacetimeClientError, + GameDistributionLineageNodeRecord, GameDistributionLineageTreeRecord, + GameDistributionOwnerGameRecord, GameDistributionPublicGameListRecordInput, + GameDistributionPublicGameRecord, GameDistributionRatingSummaryRecord, + GameDistributionRejectRecordInput, GameDistributionRestoreRecordInput, + GameDistributionReviewGameListRecordInput, GameDistributionReviewModerationOperationRecord, + GameDistributionReviewModerationRecordInput, GameDistributionSetForkAuthorizationRecordInput, + GameDistributionSubmitReviewRecordInput, GameDistributionSuspendRecordInput, + GameDistributionUnpublishRecordInput, GameDistributionUpdateMetadataRecordInput, + GameDistributionUserReviewRecord, GameDistributionVersionRecord, SpacetimeClientError, }; use tracing::{debug, info, warn}; use uuid::Uuid; @@ -1123,7 +1121,10 @@ async fn get_game_derived_games( .await .map_err(map_spacetime_error)?, )?; - Ok(json_success_body(Some(&ctx), derived_games_payload(derived))) + Ok(json_success_body( + Some(&ctx), + derived_games_payload(derived), + )) } /// 线上可见性字符串 → DTO 枚举;未知取值按「未公开」保守解释,不会因此多暴露任何信息。 @@ -1149,7 +1150,9 @@ fn lineage_node_payload(node: GameDistributionLineageNodeRecord) -> GameDistribu /// 族谱 / 衍生列表走结构化 DTO 而不是手拼 JSON:节点字段本来就少且固定, /// 用 DTO 才能让「不发对象键、不发素材键」由类型保证,而不是靠人肉回忆。 -fn lineage_tree_payload(tree: GameDistributionLineageTreeRecord) -> GameDistributionLineageResponse { +fn lineage_tree_payload( + tree: GameDistributionLineageTreeRecord, +) -> GameDistributionLineageResponse { GameDistributionLineageResponse { root_game_id: tree.root_game_id, root: tree.root.map(lineage_node_payload), @@ -2481,19 +2484,17 @@ async fn set_fork_authorization( ); let game = state .spacetime_client() - .set_game_distribution_fork_authorization( - GameDistributionSetForkAuthorizationRecordInput { - game_id, - owner_user_id, - fork_authorization: fork_authorization_value(payload.fork_authorization), - expected_fork_authorization: fork_authorization_value( - payload.expected_fork_authorization, - ), - idempotency_key, - request_digest, - now_micros: now_micros(), - }, - ) + .set_game_distribution_fork_authorization(GameDistributionSetForkAuthorizationRecordInput { + game_id, + owner_user_id, + fork_authorization: fork_authorization_value(payload.fork_authorization), + expected_fork_authorization: fork_authorization_value( + payload.expected_fork_authorization, + ), + idempotency_key, + request_digest, + now_micros: now_micros(), + }) .await .map_err(map_spacetime_error)?; Ok(json_success_body( @@ -2520,9 +2521,7 @@ fn fork_source_target( record: GameDistributionForkSourceRecord, ) -> Result { if !record.found { - return Err( - AppError::from_status(StatusCode::NOT_FOUND).with_code("FORK_SOURCE_NOT_FOUND") - ); + return Err(AppError::from_status(StatusCode::NOT_FOUND).with_code("FORK_SOURCE_NOT_FOUND")); } if !record.available { return Err( @@ -2533,9 +2532,7 @@ fn fork_source_target( module_game_distribution::ForkAuthorization::parse(record.fork_authorization.as_str()) .unwrap_or(module_game_distribution::ForkAuthorization::Forbidden); if !authorization.allows_fork() { - return Err( - AppError::from_status(StatusCode::FORBIDDEN).with_code("FORK_NOT_AUTHORIZED") - ); + return Err(AppError::from_status(StatusCode::FORBIDDEN).with_code("FORK_NOT_AUTHORIZED")); } // 失败关闭:`available` 为真却没有版本元数据时不发半截信息,按不可用处理。 let (Some(version_id), Some(package_sha256), Some(package_bytes)) = ( @@ -2668,10 +2665,7 @@ fn fork_source_package_response(game_id: &str, version_id: &str, package: Bytes) )) .unwrap_or_else(|_| HeaderValue::from_static("attachment")), ); - headers.insert( - header::CACHE_CONTROL, - HeaderValue::from_static("no-store"), - ); + headers.insert(header::CACHE_CONTROL, HeaderValue::from_static("no-store")); response } @@ -3723,9 +3717,7 @@ fn map_spacetime_error(error: SpacetimeClientError) -> AppError { let (status, code) = match code { "FORK_NOT_AUTHORIZED" => (StatusCode::FORBIDDEN, "FORK_NOT_AUTHORIZED"), "FORK_SOURCE_NOT_FOUND" => (StatusCode::NOT_FOUND, "FORK_SOURCE_NOT_FOUND"), - "FORK_SOURCE_NOT_AVAILABLE" => { - (StatusCode::CONFLICT, "FORK_SOURCE_NOT_AVAILABLE") - } + "FORK_SOURCE_NOT_AVAILABLE" => (StatusCode::CONFLICT, "FORK_SOURCE_NOT_AVAILABLE"), "FORK_SOURCE_VERSION_MISMATCH" => { (StatusCode::CONFLICT, "FORK_SOURCE_VERSION_MISMATCH") } @@ -5021,7 +5013,9 @@ mod tests { .layer(Extension(AuthenticatedAccessToken::new(claims))) // 用生产同一套 request context 中间件:错误 envelope 的 `ok` / `meta` 由它挂上的 // task-local 决定(直接手塞 Extension 只能拿到 legacy 形状,断言不到 envelope)。 - .layer(middleware::from_fn(crate::request_context::attach_request_context)) + .layer(middleware::from_fn( + crate::request_context::attach_request_context, + )) .with_state(state); for (payload, label) in [ @@ -5160,14 +5154,12 @@ mod tests { play_count: 3, status: "mystery".to_string(), }; - let tree = serde_json::to_value(lineage_tree_payload( - GameDistributionLineageTreeRecord { - root_game_id: "game-root".to_string(), - root: Some(root.clone()), - nodes: vec![root, child], - truncated: true, - }, - )) + let tree = serde_json::to_value(lineage_tree_payload(GameDistributionLineageTreeRecord { + root_game_id: "game-root".to_string(), + root: Some(root.clone()), + nodes: vec![root, child], + truncated: true, + })) .expect("族谱负载应可序列化"); assert_eq!(tree["rootGameId"], Value::String("game-root".to_string())); @@ -5203,14 +5195,13 @@ mod tests { expected_keys.sort(); assert_eq!(node_keys, expected_keys); - let derived = serde_json::to_value(derived_games_payload( - GameDistributionDerivedGamesRecord { + let derived = + serde_json::to_value(derived_games_payload(GameDistributionDerivedGamesRecord { game_id: "game-root".to_string(), nodes: Vec::new(), truncated: false, - }, - )) - .expect("衍生列表负载应可序列化"); + })) + .expect("衍生列表负载应可序列化"); assert_eq!(derived["gameId"], Value::String("game-root".to_string())); assert_eq!(derived["nodes"], Value::Array(Vec::new())); assert_eq!(derived["truncated"], Value::Bool(false)); @@ -5274,26 +5265,17 @@ mod tests { #[test] fn fork_source_target_maps_contract_status_codes() { // 行不存在 → 404;此时其余字段无意义,不得被误判成 409/403。 - let missing = fork_source_target(fork_source_record( - false, - false, - "forbidden", - None, - )) - .expect_err("行不存在必须失败"); + let missing = fork_source_target(fork_source_record(false, false, "forbidden", None)) + .expect_err("行不存在必须失败"); assert_eq!(missing.status_code(), StatusCode::NOT_FOUND); assert_eq!(missing.code(), "FORK_SOURCE_NOT_FOUND"); // 行存在但不可用(已软删除 / 未公开 / 没有当前公开版本)→ 409,且**先于**授权判定: // 未公开 + 允许共创仍然是 409,不能因为授权开放就暴露「这个 gameId 存在」。 for label in ["已软删除", "未公开", "没有当前公开版本"] { - let unavailable = fork_source_target(fork_source_record( - true, - false, - "nonCommercial", - None, - )) - .expect_err("不可用作来源必须失败"); + let unavailable = + fork_source_target(fork_source_record(true, false, "nonCommercial", None)) + .expect_err("不可用作来源必须失败"); assert_eq!(unavailable.status_code(), StatusCode::CONFLICT, "{label}"); assert_eq!(unavailable.code(), "FORK_SOURCE_NOT_AVAILABLE", "{label}"); } diff --git a/server-rs/crates/module-game-distribution/src/domain.rs b/server-rs/crates/module-game-distribution/src/domain.rs index 5dce65a36..7ba0280f7 100644 --- a/server-rs/crates/module-game-distribution/src/domain.rs +++ b/server-rs/crates/module-game-distribution/src/domain.rs @@ -408,7 +408,10 @@ mod fork_authorization_tests { }, "FORK_AUTHORIZATION_DOWNGRADE_NOT_ALLOWED", ), - (GameDistributionError::ForkNotAuthorized, "FORK_NOT_AUTHORIZED"), + ( + GameDistributionError::ForkNotAuthorized, + "FORK_NOT_AUTHORIZED", + ), ( GameDistributionError::ForkSourceNotFound, "FORK_SOURCE_NOT_FOUND", diff --git a/server-rs/crates/module-game-distribution/src/errors.rs b/server-rs/crates/module-game-distribution/src/errors.rs index 020381a7e..12bb8d7f4 100644 --- a/server-rs/crates/module-game-distribution/src/errors.rs +++ b/server-rs/crates/module-game-distribution/src/errors.rs @@ -125,12 +125,10 @@ impl fmt::Display for GameDistributionError { Self::ForkSourceNotAvailable => { formatter.write_str("FORK_SOURCE_NOT_AVAILABLE: 改编来源作品当前不可改编") } - Self::ForkSourceVersionMismatch => formatter.write_str( - "FORK_SOURCE_VERSION_MISMATCH: 改编来源版本不是该作品的当前公开版本", - ), - Self::ForkDeclarationOnExistingGame => formatter.write_str( - "FORK_DECLARATION_ON_EXISTING_GAME: 已存在的作品不能再声明改编来源", - ), + Self::ForkSourceVersionMismatch => formatter + .write_str("FORK_SOURCE_VERSION_MISMATCH: 改编来源版本不是该作品的当前公开版本"), + Self::ForkDeclarationOnExistingGame => formatter + .write_str("FORK_DECLARATION_ON_EXISTING_GAME: 已存在的作品不能再声明改编来源"), } } } diff --git a/server-rs/crates/spacetime-client/src/active.rs b/server-rs/crates/spacetime-client/src/active.rs index 6dedf85d4..0e3a1fde3 100644 --- a/server-rs/crates/spacetime-client/src/active.rs +++ b/server-rs/crates/spacetime-client/src/active.rs @@ -31,9 +31,8 @@ pub use game_distribution::{ GameDistributionPublicGameListRecordInput, GameDistributionRejectRecordInput, GameDistributionRestoreRecordInput, GameDistributionReviewGameListRecordInput, GameDistributionReviewModerationRecordInput, GameDistributionSetForkAuthorizationRecordInput, - GameDistributionSubmitReviewRecordInput, - GameDistributionSuspendRecordInput, GameDistributionUnpublishRecordInput, - GameDistributionUpdateMetadataRecordInput, + GameDistributionSubmitReviewRecordInput, GameDistributionSuspendRecordInput, + GameDistributionUnpublishRecordInput, GameDistributionUpdateMetadataRecordInput, }; #[path = "active/external_generation.rs"] pub mod external_generation; diff --git a/server-rs/crates/spacetime-client/src/active/mapper/game_distribution.rs b/server-rs/crates/spacetime-client/src/active/mapper/game_distribution.rs index 0d1cbf3c6..ddd899736 100644 --- a/server-rs/crates/spacetime-client/src/active/mapper/game_distribution.rs +++ b/server-rs/crates/spacetime-client/src/active/mapper/game_distribution.rs @@ -582,11 +582,7 @@ pub(crate) fn map_game_distribution_public_game_list_result( if !result.ok { return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - Ok(result - .games - .into_iter() - .map(map_public_game) - .collect()) + Ok(result.games.into_iter().map(map_public_game).collect()) } pub(crate) fn map_game_distribution_version_result( diff --git a/server-rs/crates/spacetime-client/src/game_distribution.rs b/server-rs/crates/spacetime-client/src/game_distribution.rs index 97d1abe75..335e96f12 100644 --- a/server-rs/crates/spacetime-client/src/game_distribution.rs +++ b/server-rs/crates/spacetime-client/src/game_distribution.rs @@ -662,12 +662,15 @@ impl SpacetimeClient { move |connection, sender| { connection .procedures() - .list_game_distribution_derived_games_and_return_then(input, move |_, result| { - let mapped = result - .map_err(SpacetimeClientError::from_sdk_error) - .and_then(map_game_distribution_derived_games_result); - send_once(&sender, mapped); - }); + .list_game_distribution_derived_games_and_return_then( + input, + move |_, result| { + let mapped = result + .map_err(SpacetimeClientError::from_sdk_error) + .and_then(map_game_distribution_derived_games_result); + send_once(&sender, mapped); + }, + ); }, ) .await diff --git a/server-rs/crates/spacetime-module/src/game_distribution.rs b/server-rs/crates/spacetime-module/src/game_distribution.rs index 949bd5735..7c4d8ce32 100644 --- a/server-rs/crates/spacetime-module/src/game_distribution.rs +++ b/server-rs/crates/spacetime-module/src/game_distribution.rs @@ -2194,8 +2194,9 @@ fn resolve_game_distribution_fork_declaration_tx( module_game_distribution::GameDistributionError::ForkSourceNotAvailable.to_string() })?; if current_version_id.as_str() != forked_from_version_id { - return Err(module_game_distribution::GameDistributionError::ForkSourceVersionMismatch - .to_string()); + return Err( + module_game_distribution::GameDistributionError::ForkSourceVersionMismatch.to_string(), + ); } let (root_game_id, parent_generation) = match ctx .db @@ -2285,8 +2286,10 @@ fn create_game_distribution_game_tx( if let Some(game) = existing { // 复用既有作品身份时不允许再声明改编来源:否则会把别人的原创作改判成衍生作品。 if fork_resolution.is_some() { - return Err(module_game_distribution::GameDistributionError::ForkDeclarationOnExistingGame - .to_string()); + return Err( + module_game_distribution::GameDistributionError::ForkDeclarationOnExistingGame + .to_string(), + ); } insert_game_distribution_receipt( ctx, @@ -4221,9 +4224,7 @@ fn get_game_distribution_fork_source_tx( found: true, available, fork_authorization: game.fork_authorization.clone(), - version_id: version - .as_ref() - .map(|version| version.version_id.clone()), + version_id: version.as_ref().map(|version| version.version_id.clone()), package_sha256: version .as_ref() .map(|version| version.package_sha256.clone()), @@ -4254,7 +4255,12 @@ fn game_distribution_lineage_entries( .by_game_distribution_lineage_root_game_id() .filter(&root_game_id.to_string()) { - let Some(game) = ctx.db.game_distribution_game().game_id().find(&lineage.game_id) else { + let Some(game) = ctx + .db + .game_distribution_game() + .game_id() + .find(&lineage.game_id) + else { continue; }; entries.push(game_distribution_lineage_entry(