diff options
| author | Polesznyák Márk László <116908301+pml68@users.noreply.github.com> | 2025-03-23 02:49:57 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-23 02:49:57 +0100 |
| commit | 3076889c00116b22f022792471253e7188c6e93e (patch) | |
| tree | bff0cda7a9152e9f94d3176bbf5acaf879394f5f /src/values/line_height.rs | |
| parent | feat: update to Rust 2024 (diff) | |
| parent | feat: finish `ApplyOptions` impls (diff) | |
| download | iced-builder-3076889c00116b22f022792471253e7188c6e93e.tar.gz | |
Merge pull request #7 from pml68/feat/options-backend
Options backend done (for now)
Diffstat (limited to '')
| -rw-r--r-- | src/values/line_height.rs | 117 |
1 files changed, 117 insertions, 0 deletions
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)) + } +} |
