为绑定区域校验引入类型错误

用 ZeroDimension 和 OutOfBounds 区分边界校验失败

补充 typed error 单元测试并保留展示层中文文案
This commit is contained in:
2026-09-12 10:20:17 +08:00
parent 319aa69d6e
commit 69ce232a74
@@ -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<BindingDecision>,
}
#[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)
);
}
}