Files
Genarrative/server-rs/crates/module-square-hole/src/commands.rs
kdletters d06107f2c6
Some checks failed
CI / verify (push) Has been cancelled
落地方洞挑战图片与运行态交互
2026-05-06 12:52:47 +08:00

102 lines
3.7 KiB
Rust

use shared_kernel::{normalize_required_string, normalize_string_list};
use crate::{
SQUARE_HOLE_MAX_DIFFICULTY, SQUARE_HOLE_MAX_SHAPE_COUNT, SQUARE_HOLE_MIN_DIFFICULTY,
SQUARE_HOLE_MIN_SHAPE_COUNT, SquareHoleCreatorConfig, SquareHoleError, SquareHoleResultDraft,
normalize_hole_options, normalize_shape_options,
};
pub fn validate_shape_count(value: u32) -> Result<u32, SquareHoleError> {
if (SQUARE_HOLE_MIN_SHAPE_COUNT..=SQUARE_HOLE_MAX_SHAPE_COUNT).contains(&value) {
Ok(value)
} else {
Err(SquareHoleError::InvalidShapeCount)
}
}
pub fn validate_difficulty(value: u32) -> Result<u32, SquareHoleError> {
if (SQUARE_HOLE_MIN_DIFFICULTY..=SQUARE_HOLE_MAX_DIFFICULTY).contains(&value) {
Ok(value)
} else {
Err(SquareHoleError::InvalidDifficulty)
}
}
pub fn normalize_theme_text(value: impl AsRef<str>) -> Result<String, SquareHoleError> {
normalize_required_string(value).ok_or(SquareHoleError::MissingText)
}
pub fn build_creator_config(
theme_text: &str,
twist_rule: &str,
shape_count: u32,
difficulty: u32,
) -> Result<SquareHoleCreatorConfig, SquareHoleError> {
let hole_options = normalize_hole_options(Vec::new(), theme_text);
Ok(SquareHoleCreatorConfig {
theme_text: normalize_theme_text(theme_text)?,
twist_rule: normalize_required_string(twist_rule).ok_or(SquareHoleError::MissingText)?,
shape_count: validate_shape_count(shape_count)?,
difficulty: validate_difficulty(difficulty)?,
shape_options: normalize_shape_options(Vec::new(), theme_text, hole_options.as_slice()),
hole_options,
background_prompt: format!("{theme_text}主题的竖屏游戏背景,舞台中央有多个形状洞口"),
cover_image_src: None,
background_image_src: None,
})
}
pub fn build_default_tags(theme_text: &str) -> Vec<String> {
normalize_string_list(vec![
"方洞挑战".to_string(),
theme_text.to_string(),
"反直觉".to_string(),
])
}
pub fn default_tags_for_theme(theme_text: &str) -> Vec<String> {
let mut tags = vec![
"方洞挑战".to_string(),
"反直觉".to_string(),
theme_text.to_string(),
];
tags.sort();
tags.dedup();
tags
}
pub fn validate_publish_requirements(draft: &SquareHoleResultDraft) -> Vec<String> {
let mut blockers = Vec::new();
if normalize_required_string(&draft.game_name).is_none() {
blockers.push("游戏名称不能为空".to_string());
}
if normalize_required_string(&draft.summary).is_none() {
blockers.push("简介不能为空".to_string());
}
if normalize_required_string(&draft.theme_text).is_none() {
blockers.push("题材不能为空".to_string());
}
if normalize_required_string(&draft.twist_rule).is_none() {
blockers.push("反直觉规则不能为空".to_string());
}
if normalize_string_list(draft.tags.clone()).is_empty() {
blockers.push("至少需要 1 个标签".to_string());
}
if validate_shape_count(draft.shape_count).is_err() {
blockers.push(format!(
"形状数量必须在 {}{} 之间",
SQUARE_HOLE_MIN_SHAPE_COUNT, SQUARE_HOLE_MAX_SHAPE_COUNT
));
}
if validate_difficulty(draft.difficulty).is_err() {
blockers.push("难度必须在 1 到 10 之间".to_string());
}
if draft.shape_options.len() < crate::SQUARE_HOLE_MIN_SHAPE_OPTION_COUNT {
blockers.push("至少需要 6 个形状图片选项".to_string());
}
if draft.hole_options.len() < crate::SQUARE_HOLE_MIN_HOLE_OPTION_COUNT {
blockers.push("至少需要 3 个洞口选项".to_string());
}
blockers
}