diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/model/binding.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/model/binding.rs index d24f249eb..e527c7613 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/model/binding.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/model/binding.rs @@ -2,6 +2,23 @@ use crate::ui_editor::utils::NodeId; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum BindingAreaValidationError { + ZeroDimension, + OutOfBounds, +} + +impl std::fmt::Display for BindingAreaValidationError { + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str(match self { + Self::ZeroDimension => "BindingArea 宽度和高度必须大于 0", + Self::OutOfBounds => "BindingArea 超出处理图边界", + }) + } +} + +impl std::error::Error for BindingAreaValidationError {} + #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize, JsonSchema)] #[schemars(deny_unknown_fields)] pub struct BindingArea { @@ -12,9 +29,9 @@ pub struct BindingArea { } impl BindingArea { - pub fn validate_in(&self, w: u32, h: u32) -> Result<(), String> { + pub fn validate_in(&self, w: u32, h: u32) -> Result<(), BindingAreaValidationError> { if self.width_px == 0 || self.height_px == 0 { - return Err("BindingArea 宽度和高度必须大于 0".into()); + return Err(BindingAreaValidationError::ZeroDimension); } if self .global_pos_x_px @@ -25,7 +42,7 @@ impl BindingArea { .checked_add(self.height_px) .is_none_or(|v| v > h) { - return Err("BindingArea 超出处理图边界".into()); + return Err(BindingAreaValidationError::OutOfBounds); } Ok(()) } @@ -48,3 +65,33 @@ pub enum BindingDecision { pub struct BindingResp { pub decisions: Vec, } + +#[cfg(test)] +mod tests { + use super::{BindingArea, BindingAreaValidationError}; + + #[test] + fn validates_binding_area_with_typed_errors() { + let zero = BindingArea { + global_pos_x_px: 0, + global_pos_y_px: 0, + width_px: 0, + height_px: 1, + }; + assert_eq!( + zero.validate_in(10, 10), + Err(BindingAreaValidationError::ZeroDimension) + ); + + let outside = BindingArea { + global_pos_x_px: 10, + global_pos_y_px: 0, + width_px: 1, + height_px: 1, + }; + assert_eq!( + outside.validate_in(10, 10), + Err(BindingAreaValidationError::OutOfBounds) + ); + } +}