Preserve partial creation replies on stream failure
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
kdletters
2026-05-05 11:31:50 +08:00
parent 100fee7e7a
commit 995661e7cc
299 changed files with 13805 additions and 1429 deletions

View File

@@ -0,0 +1,116 @@
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,
};
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> {
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)?,
})
}
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());
}
blockers
}
#[deprecated(note = "请使用 compile_result_draft(profile_id, &config)")]
pub fn build_result_draft(
profile_id: String,
theme_text: String,
twist_rule: String,
shape_count: u32,
difficulty: u32,
) -> SquareHoleResultDraft {
let game_name = format!("{theme_text}方洞挑战");
let summary = format!(
"{theme_text}主题,{} 个形状,难度 {},规则:{twist_rule}",
shape_count, difficulty
);
let blockers = Vec::new();
SquareHoleResultDraft {
profile_id,
game_name,
theme_text,
twist_rule,
summary,
tags: build_default_tags("方洞挑战"),
shape_count,
difficulty,
publish_ready: true,
blockers,
}
}