328ac31844
- 主站:游戏广场、详情、在线游玩、网页发布与作者中心,以及共享契约与客户端服务 - 后端:module-game-distribution 领域层、SpacetimeDB 表/迁移/绑定、spacetime-client facade、api-server 路由与发行网关 - 后台:游戏审核页(待审列表、通过/拒绝、安全下架) - AGC:发布面板、本地导出包读取命令与发布服务,含默认跳过的真实链路测试 - 运维:发行来源 nginx 模板与门禁、game-distribution:publish 灰度发布开关、OSS PutObject 受控重试 - 文档:主规范、里程碑与实施计划、决策日志与踩坑记录
106 lines
4.0 KiB
Rust
106 lines
4.0 KiB
Rust
use std::{error::Error, fmt};
|
|
|
|
use crate::{GameVersionStatus, GameVisibility};
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
pub enum GameDistributionFieldError {
|
|
MissingGameId,
|
|
MissingVersionId,
|
|
MissingOwnerUserId,
|
|
MissingActorUserId,
|
|
MissingIdempotencyKey,
|
|
MissingRequestDigest,
|
|
InvalidPackageDigest,
|
|
InvalidPackageBytes,
|
|
MissingReviewReason,
|
|
}
|
|
|
|
impl fmt::Display for GameDistributionFieldError {
|
|
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
let message = match self {
|
|
Self::MissingGameId => "gameId 不能为空",
|
|
Self::MissingVersionId => "versionId 不能为空",
|
|
Self::MissingOwnerUserId => "ownerUserId 不能为空",
|
|
Self::MissingActorUserId => "actorUserId 不能为空",
|
|
Self::MissingIdempotencyKey => "Idempotency-Key 不能为空",
|
|
Self::MissingRequestDigest => "request digest 不能为空",
|
|
Self::InvalidPackageDigest => "packageSha256 必须是 64 位十六进制摘要",
|
|
Self::InvalidPackageBytes => "packageBytes 必须大于 0",
|
|
Self::MissingReviewReason => "拒绝审核必须提供理由",
|
|
};
|
|
formatter.write_str(message)
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
pub enum GameDistributionError {
|
|
Field(GameDistributionFieldError),
|
|
GameNotFound,
|
|
VersionNotFound,
|
|
GameAlreadyExists,
|
|
VersionAlreadyExists,
|
|
Forbidden,
|
|
IdempotencyConflict,
|
|
IdempotencyOutcomeMismatch,
|
|
InvalidVersionTransition {
|
|
from: GameVersionStatus,
|
|
to: GameVersionStatus,
|
|
},
|
|
PublicationConflict {
|
|
expected: u64,
|
|
actual: u64,
|
|
},
|
|
PackageMismatch,
|
|
GameSuspended,
|
|
GameNotPublished,
|
|
VersionNotPublished,
|
|
VersionAlreadyPublished,
|
|
ReviewActionNotAllowed,
|
|
}
|
|
|
|
impl fmt::Display for GameDistributionError {
|
|
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
Self::Field(field) => field.fmt(formatter),
|
|
Self::GameNotFound => formatter.write_str("游戏不存在"),
|
|
Self::VersionNotFound => formatter.write_str("游戏版本不存在"),
|
|
Self::GameAlreadyExists => formatter.write_str("游戏已存在"),
|
|
Self::VersionAlreadyExists => formatter.write_str("游戏版本已存在"),
|
|
Self::Forbidden => formatter.write_str("无权操作该游戏"),
|
|
Self::IdempotencyConflict => formatter.write_str("幂等键对应的请求摘要不一致"),
|
|
Self::IdempotencyOutcomeMismatch => formatter.write_str("幂等记录结果类型不一致"),
|
|
Self::InvalidVersionTransition { from, to } => {
|
|
write!(formatter, "版本状态不能从 {from:?} 变为 {to:?}")
|
|
}
|
|
Self::PublicationConflict { expected, actual } => {
|
|
write!(
|
|
formatter,
|
|
"公开状态版本冲突:期望 {expected},实际 {actual}"
|
|
)
|
|
}
|
|
Self::PackageMismatch => formatter.write_str("发行包摘要或字节数与版本声明不一致"),
|
|
Self::GameSuspended => formatter.write_str("游戏已被管理员下架"),
|
|
Self::GameNotPublished => formatter.write_str("游戏当前未公开"),
|
|
Self::VersionNotPublished => formatter.write_str("游戏版本当前未公开"),
|
|
Self::VersionAlreadyPublished => formatter.write_str("游戏版本已经公开"),
|
|
Self::ReviewActionNotAllowed => formatter.write_str("当前版本不允许审核操作"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Error for GameDistributionError {}
|
|
|
|
impl From<GameDistributionFieldError> for GameDistributionError {
|
|
fn from(value: GameDistributionFieldError) -> Self {
|
|
Self::Field(value)
|
|
}
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
fn _visibility_is_exhaustive(visibility: GameVisibility) -> bool {
|
|
matches!(
|
|
visibility,
|
|
GameVisibility::Unpublished | GameVisibility::Published | GameVisibility::Suspended
|
|
)
|
|
}
|