style(游戏共创): 按 rustfmt 修正本分支新增代码的格式(无语义变化)
判定依据(先判定再动手):仓库根 `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)仍通过。
This commit is contained in:
@@ -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<ForkSourceTarget, AppError> {
|
||||
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}");
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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: 已存在的作品不能再声明改编来源"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user