diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/component/text.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/component/text.rs index 092e8fc0c..46291e831 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/component/text.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/component/text.rs @@ -2,7 +2,7 @@ use crate::ui_editor::component::common::error::ComponentValueError; use crate::ui_editor::resource::sprite::{Color, WHITE}; use crate::ui_editor::utils::FontAssetId; use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use serde::{de::Deserializer, Deserialize, Serialize}; use std::num::NonZeroU32; use ts_rs::TS; use typed_floats::tf32::StrictlyPositiveFinite; @@ -44,13 +44,29 @@ pub enum VerticalTextOverflow { Overflow, } -#[derive(Clone, Copy, Debug, Deserialize, JsonSchema, PartialEq, Serialize, TS)] +#[derive(Clone, Copy, Debug, JsonSchema, PartialEq, Serialize, TS)] #[ts(export, export_to = concat!(env!("CARGO_MANIFEST_DIR"), "/../src/features/ui-editor/types/"))] pub struct BestFitFontSize { min: NonZeroU32, max: NonZeroU32, } +impl<'de> Deserialize<'de> for BestFitFontSize { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + struct RawBestFitFontSize { + min: NonZeroU32, + max: NonZeroU32, + } + + let raw = RawBestFitFontSize::deserialize(deserializer)?; + Self::new(raw.min, raw.max).map_err(serde::de::Error::custom) + } +} + impl BestFitFontSize { pub fn new(min: NonZeroU32, max: NonZeroU32) -> Result { if min > max { @@ -129,6 +145,29 @@ impl Default for TextComponent { } } +#[cfg(test)] +mod best_fit_tests { + use super::{BestFitFontSize, FontSizing}; + + #[test] + fn best_fit_font_size_is_validated_when_deserialized() { + let valid: BestFitFontSize = + serde_json::from_value(serde_json::json!({ "min": 12, "max": 24 })) + .expect("valid font-size range"); + assert_eq!(valid.min().get(), 12); + assert_eq!(valid.max().get(), 24); + + assert!(serde_json::from_value::( + serde_json::json!({ "min": 24, "max": 12 }), + ) + .is_err()); + assert!(serde_json::from_value::( + serde_json::json!({ "BestFit": { "min": 24, "max": 12 } }), + ) + .is_err()); + } +} + #[cfg(test)] mod tests { use super::*;