diff options
| author | pml68 <contact@pml68.dev> | 2025-03-04 00:01:42 +0100 |
|---|---|---|
| committer | pml68 <contact@pml68.dev> | 2025-03-04 00:01:42 +0100 |
| commit | 107998a3a53c1f4c008837a0099fd22bddfb1802 (patch) | |
| tree | 026b4e661db8767c9c2479f40a86ad0a3e0c8adf /src | |
| parent | refactor: move some `assert_eq`s (diff) | |
| download | iced-builder-107998a3a53c1f4c008837a0099fd22bddfb1802.tar.gz | |
feat: impl `Value` for `LineHeight` and `ContentFit` (all done)
Diffstat (limited to '')
| -rw-r--r-- | src/values.rs | 2 | ||||
| -rw-r--r-- | src/values/content_fit.rs | 69 | ||||
| -rw-r--r-- | src/values/line_height.rs | 117 |
3 files changed, 188 insertions, 0 deletions
diff --git a/src/values.rs b/src/values.rs index a788dab..6033d00 100644 --- a/src/values.rs +++ b/src/values.rs @@ -1,5 +1,7 @@ mod alignment; +mod content_fit; mod length; +mod line_height; mod padding; mod pixels; mod rotation; diff --git a/src/values/content_fit.rs b/src/values/content_fit.rs new file mode 100644 index 0000000..053431f --- /dev/null +++ b/src/values/content_fit.rs @@ -0,0 +1,69 @@ +use iced::ContentFit; + +use super::Value; + +#[derive(Debug, thiserror::Error, Clone, PartialEq)] +pub enum ParseContentFitError { + #[error("invalid variant")] + InvalidVariant, +} + +impl Value for ContentFit { + type Err = ParseContentFitError; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + let s = s.trim(); + + if s.is_empty() { + Ok(Self::default()) + } else { + match s { + "fill" => Ok(Self::Fill), + "none" => Ok(Self::None), + "cover" => Ok(Self::Cover), + "contain" => Ok(Self::Contain), + "scale_down" => Ok(Self::ScaleDown), + _ => Err(ParseContentFitError::InvalidVariant), + } + } + } + + fn to_string(&self) -> String { + match self { + Self::Fill => String::from("fill"), + Self::None => String::from("none"), + Self::Cover => String::from("cover"), + Self::Contain => String::from("contain"), + Self::ScaleDown => String::from("scale_down"), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_parse_with_spaces() { + assert_eq!(ContentFit::from_str(" fill"), Ok(ContentFit::Fill)); + + assert_eq!(ContentFit::from_str(" none "), Ok(ContentFit::None)); + + assert_eq!(ContentFit::from_str("cover "), Ok(ContentFit::Cover)); + + assert_eq!(ContentFit::from_str("contain"), Ok(ContentFit::Contain)); + + assert_eq!( + ContentFit::from_str("scale_down"), + Ok(ContentFit::ScaleDown) + ) + } + + #[test] + fn cant_parse_invalid_variant() { + assert_eq!( + ContentFit::from_str("clip"), + Err(ParseContentFitError::InvalidVariant) + ) + } +} diff --git a/src/values/line_height.rs b/src/values/line_height.rs new file mode 100644 index 0000000..0ea1524 --- /dev/null +++ b/src/values/line_height.rs @@ -0,0 +1,117 @@ +use std::num::ParseFloatError; +use std::str::FromStr; + +use iced::Pixels; +use iced::advanced::text::LineHeight; + +use super::Value; + +#[derive(Debug, thiserror::Error, Clone, PartialEq)] +pub enum ParseLineHeightError { + #[error("float parsing error: {0}")] + ParseFloatError(ParseFloatError), + #[error("missing prefix")] + MissingPrefix, + #[error("invalid prefix")] + InvalidPrefix, + #[error("cannot parse line height from empty string")] + Empty, +} + +impl From<ParseFloatError> for ParseLineHeightError { + fn from(value: ParseFloatError) -> Self { + Self::ParseFloatError(value) + } +} + +impl Value for LineHeight { + type Err = ParseLineHeightError; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + let s = s.trim(); + + if s.is_empty() { + return Err(ParseLineHeightError::Empty); + } + + if s.starts_with(|c: char| !c.is_ascii_digit()) { + let (prefix, value) = s.split_at(1); + match prefix.to_lowercase().as_str() { + "r" => Ok(Self::Relative(f32::from_str(value)?)), + "a" => Ok(Self::Absolute(Pixels::from_str(value)?)), + _ => Err(ParseLineHeightError::InvalidPrefix), + } + } else { + Err(ParseLineHeightError::MissingPrefix) + } + } + + fn to_string(&self) -> String { + match self { + Self::Relative(value) => format!("r{}", value), + Self::Absolute(value) => format!("a{}", value.0), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_parse_with_r_prefix() { + assert_eq!( + LineHeight::from_str(" r3.2"), + Ok(LineHeight::Relative(3.2)) + ); + + assert_eq!( + LineHeight::from_str(" R6.5 "), + Ok(LineHeight::Relative(6.5)) + ) + } + + #[test] + fn can_parse_with_a_prefix() { + assert_eq!( + LineHeight::from_str("a9.4 "), + Ok(LineHeight::Absolute(Pixels(9.4))) + ); + + assert_eq!( + LineHeight::from_str("A1.3"), + Ok(LineHeight::Absolute(Pixels(1.3))) + ) + } + + #[test] + fn cant_parse_with_missing_prefix() { + assert_eq!( + LineHeight::from_str("5.1"), + Err(ParseLineHeightError::MissingPrefix) + ) + } + + #[test] + fn cant_parse_invalid_prefix() { + assert_eq!( + LineHeight::from_str("g21"), + Err(ParseLineHeightError::InvalidPrefix) + ) + } + + #[test] + fn cant_parse_invalid_float() { + assert_eq!( + LineHeight::from_str("a2f"), + Err(ParseLineHeightError::ParseFloatError( + f32::from_str("2f").expect_err("float parse should fail") + )) + ) + } + + #[test] + fn cant_parse_empty_string() { + assert_eq!(LineHeight::from_str(" "), Err(ParseLineHeightError::Empty)) + } +} |
