//! 运行时领域错误。 //! //! 错误保持运行时业务语义,例如快照版本非法、兑换码不可用或钱包余额不足。 use crate::{ MAX_BROWSE_HISTORY_BATCH_SIZE, PROFILE_FEEDBACK_CONTACT_PHONE_MAX_CHARS, PROFILE_FEEDBACK_DESCRIPTION_MAX_CHARS, PROFILE_FEEDBACK_DESCRIPTION_MIN_CHARS, PROFILE_FEEDBACK_EVIDENCE_MAX_BYTES, PROFILE_FEEDBACK_EVIDENCE_MAX_COUNT, PROFILE_FEEDBACK_EVIDENCE_TOTAL_MAX_BYTES, }; #[derive(Clone, Debug, PartialEq, Eq)] pub enum RuntimeSettingsFieldError { MissingUserId, } impl std::fmt::Display for RuntimeSettingsFieldError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::MissingUserId => f.write_str("runtime_setting.user_id 不能为空"), } } } #[derive(Clone, Debug, PartialEq, Eq)] pub enum RuntimeBrowseHistoryFieldError { MissingUserId, TooManyEntries, } impl std::fmt::Display for RuntimeBrowseHistoryFieldError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::MissingUserId => f.write_str("browse_history.user_id 不能为空"), Self::TooManyEntries => write!( f, "browse_history.entries 单次最多只允许 {} 条", MAX_BROWSE_HISTORY_BATCH_SIZE ), } } } #[derive(Clone, Debug, PartialEq, Eq)] pub enum RuntimeProfileFieldError { MissingUserId, MissingLedgerId, InvalidWalletAmount, WalletAmountOverflow, WalletBalanceOverflow, InsufficientWalletBalance, MissingInviteCode, MissingRedeemCode, RedeemCodeDisabled, RedeemCodeUsesExhausted, RedeemCodeNotAllowedForUser, InvalidRedeemCodeReward, InvalidRedeemCodeMaxUses, InvalidInviteCodeMetadata, InvalidUserTag, InvalidInviteCodeValidityWindow, MissingTaskId, MissingTaskTitle, MissingTaskEventKey, MissingTrackingEventId, MissingTrackingScopeId, InvalidTaskCycle, InvalidTaskScopeKind, UnsupportedProfileTaskScopeKind, InvalidTaskThreshold, InvalidTaskReward, TaskDisabled, TaskNotClaimable, TaskAlreadyClaimed, MissingProductId, MissingWorldKey, MissingBottomTab, MissingCheckpointSessionId, UnknownRechargeProduct, InvalidGameStateJson, InvalidCurrentStoryJson, MissingRuntimeSessionId, RuntimeSessionMismatch { expected_session_id: String, actual_session_id: String, }, NonPersistentRuntimeSnapshot, InvalidAnalyticsCalendarDate, MissingFeedbackDescription, FeedbackDescriptionTooShort, FeedbackDescriptionTooLong, FeedbackContactPhoneTooLong, TooManyFeedbackEvidenceItems, InvalidFeedbackEvidenceContentType, InvalidFeedbackEvidenceDataUrl, FeedbackEvidenceTooLarge, FeedbackEvidenceTotalTooLarge, } impl std::fmt::Display for RuntimeProfileFieldError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::MissingUserId => f.write_str("profile.user_id 不能为空"), Self::MissingLedgerId => f.write_str("profile.wallet_ledger_id 不能为空"), Self::InvalidWalletAmount => f.write_str("profile.wallet_amount 必须大于 0"), Self::WalletAmountOverflow => f.write_str("profile.wallet_amount 超出上限"), Self::WalletBalanceOverflow => f.write_str("profile.wallet_balance 超出上限"), Self::InsufficientWalletBalance => f.write_str("光点余额不足"), Self::MissingInviteCode => f.write_str("referral.invite_code 不能为空"), Self::MissingRedeemCode => f.write_str("兑换码不能为空"), Self::RedeemCodeDisabled => f.write_str("兑换码已停用"), Self::RedeemCodeUsesExhausted => f.write_str("兑换次数已用完"), Self::RedeemCodeNotAllowedForUser => f.write_str("该兑换码不适用于当前账号"), Self::InvalidRedeemCodeReward => f.write_str("兑换码奖励无效"), Self::InvalidRedeemCodeMaxUses => f.write_str("兑换次数必须大于 0"), Self::InvalidInviteCodeMetadata => { f.write_str("邀请码 metadata 必须是合法 JSON object") } Self::InvalidUserTag => f.write_str("用户标签格式无效"), Self::InvalidInviteCodeValidityWindow => f.write_str("邀请码开始时间不能晚于截止时间"), Self::MissingTaskId => f.write_str("profile_task.task_id 不能为空"), Self::MissingTaskTitle => f.write_str("profile_task.title 不能为空"), Self::MissingTaskEventKey => f.write_str("profile_task.event_key 不能为空"), Self::MissingTrackingEventId => f.write_str("tracking_event.event_id 不能为空"), Self::MissingTrackingScopeId => f.write_str("tracking_event.scope_id 不能为空"), Self::InvalidTaskCycle => f.write_str("profile_task.cycle 无效"), Self::InvalidTaskScopeKind => f.write_str("profile_task.scope_kind 无效"), Self::UnsupportedProfileTaskScopeKind => { f.write_str("个人任务 scope_kind 首版仅支持 user") } Self::InvalidTaskThreshold => f.write_str("profile_task.threshold 必须大于 0"), Self::InvalidTaskReward => f.write_str("profile_task.reward_points 必须大于 0"), Self::TaskDisabled => f.write_str("任务已停用"), Self::TaskNotClaimable => f.write_str("任务尚未达成"), Self::TaskAlreadyClaimed => f.write_str("任务奖励已领取"), Self::MissingProductId => f.write_str("recharge.product_id 不能为空"), Self::MissingWorldKey => f.write_str("profile.world_key 不能为空"), Self::MissingBottomTab => f.write_str("runtime_snapshot.bottom_tab 不能为空"), Self::MissingCheckpointSessionId => f.write_str("checkpoint.session_id 不能为空"), Self::UnknownRechargeProduct => f.write_str("recharge.product_id 不存在"), Self::InvalidGameStateJson => { f.write_str("runtime_snapshot.game_state 必须是合法 JSON") } Self::InvalidCurrentStoryJson => { f.write_str("runtime_snapshot.current_story 必须是合法 JSON object 或 null") } Self::MissingRuntimeSessionId => { f.write_str("服务端运行时快照缺少 runtimeSessionId,无法创建 checkpoint") } Self::RuntimeSessionMismatch { .. } => { f.write_str("checkpoint sessionId 与服务端运行时快照不一致") } Self::NonPersistentRuntimeSnapshot => { f.write_str("预览或测试运行态不能创建正式 checkpoint") } Self::InvalidAnalyticsCalendarDate => { f.write_str("analytics_date_dimension.calendar_date 必须是合法 YYYY-MM-DD 日期") } Self::MissingFeedbackDescription => f.write_str("反馈问题描述不能为空"), Self::FeedbackDescriptionTooShort => write!( f, "请填写{}个字以上的问题描述", PROFILE_FEEDBACK_DESCRIPTION_MIN_CHARS ), Self::FeedbackDescriptionTooLong => write!( f, "问题描述不能超过 {} 字", PROFILE_FEEDBACK_DESCRIPTION_MAX_CHARS ), Self::FeedbackContactPhoneTooLong => write!( f, "联系电话不能超过 {} 字", PROFILE_FEEDBACK_CONTACT_PHONE_MAX_CHARS ), Self::TooManyFeedbackEvidenceItems => { write!(f, "最多上传{}张凭证", PROFILE_FEEDBACK_EVIDENCE_MAX_COUNT) } Self::InvalidFeedbackEvidenceContentType => f.write_str("反馈凭证只支持图片类型"), Self::InvalidFeedbackEvidenceDataUrl => f.write_str("反馈凭证图片数据无效"), Self::FeedbackEvidenceTooLarge => write!( f, "单张反馈凭证不能超过 {} bytes", PROFILE_FEEDBACK_EVIDENCE_MAX_BYTES ), Self::FeedbackEvidenceTotalTooLarge => write!( f, "反馈凭证总大小不能超过 {} bytes", PROFILE_FEEDBACK_EVIDENCE_TOTAL_MAX_BYTES ), } } }