102 lines
3.7 KiB
Rust
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
|
|
}
|