From fb58080059510de9293fddaad7c543a3089b3824 Mon Sep 17 00:00:00 2001 From: pml68 Date: Mon, 24 Feb 2025 22:31:58 +0100 Subject: feat: implement `ValueFromStr` for Rotation --- src/values/padding.rs | 76 +++++++++++++++++++++++++++++++++++--------------- src/values/rotation.rs | 37 ++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 22 deletions(-) create mode 100644 src/values/rotation.rs (limited to 'src/values') diff --git a/src/values/padding.rs b/src/values/padding.rs index 3cec7a7..01e333b 100644 --- a/src/values/padding.rs +++ b/src/values/padding.rs @@ -1,37 +1,69 @@ +use std::num::ParseFloatError; use std::str::FromStr; use iced::Padding; use super::ValueFromStr; -#[derive(Debug)] +#[derive(Debug, thiserror::Error)] pub enum PaddingError { - Nah, + #[error("wrong number of values")] + WrongNumberOfValues, + #[error("float parsing error: {0}")] + ParseFloatError(ParseFloatError), + #[error("missing bracket")] + MissingBracket, + #[error("empty string given")] + Empty, +} + +impl From for PaddingError { + fn from(value: ParseFloatError) -> Self { + Self::ParseFloatError(value) + } } impl ValueFromStr for Padding { type Err = PaddingError; fn value_from_str(s: &str) -> Result { - s.strip_prefix('[') - .and_then(|s| s.strip_suffix(']')) - .map(|s| { - s.split(',') - .map(|n| f32::from_str(n).unwrap()) - .collect::>() - }) - .and_then(|s| { - if s.len() == 4 { - Some(Padding { - top: s[0], - right: s[1], - bottom: s[2], - left: s[3], - }) - } else { - None - } - }) - .ok_or(PaddingError::Nah) + if s.is_empty() { + return Err(PaddingError::Empty); + } + let values = s + .strip_prefix('[') + .ok_or(PaddingError::MissingBracket)? + .strip_suffix(']') + .ok_or(PaddingError::MissingBracket)? + .split(',') + .map(|n| f32::from_str(n)) + .collect::, _>>()?; + match values.len() { + 1 => Ok(Padding { + top: values[0], + right: values[0], + bottom: values[0], + left: values[0], + }), + 2 => Ok(Padding { + top: values[0], + right: values[1], + bottom: values[0], + left: values[1], + }), + 3 => Ok(Padding { + top: values[0], + right: values[1], + bottom: values[2], + left: values[1], + }), + 4 => Ok(Padding { + top: values[0], + right: values[1], + bottom: values[2], + left: values[3], + }), + _ => Err(PaddingError::WrongNumberOfValues), + } } } diff --git a/src/values/rotation.rs b/src/values/rotation.rs new file mode 100644 index 0000000..2b7a223 --- /dev/null +++ b/src/values/rotation.rs @@ -0,0 +1,37 @@ +use std::num::ParseFloatError; +use std::str::FromStr; + +use iced::{Radians, Rotation}; + +use super::ValueFromStr; + +#[derive(Debug, thiserror::Error)] +pub enum ParseRotationError { + #[error("float parsing error: {0}")] + ParseFloatError(ParseFloatError), + #[error("invalid prefix")] + InvalidPrefix, +} + +impl From for ParseRotationError { + fn from(value: ParseFloatError) -> Self { + Self::ParseFloatError(value) + } +} + +impl ValueFromStr for Rotation { + type Err = ParseRotationError; + + fn value_from_str(s: &str) -> Result { + if s.starts_with(|c: char| !c.is_digit(10)) { + let (prefix, value) = s.split_at(1); + match prefix { + "s" => Ok(Rotation::Solid(Radians(f32::from_str(value)?))), + "f" => Ok(Rotation::Floating(Radians(f32::from_str(value)?))), + _ => Err(ParseRotationError::InvalidPrefix), + } + } else { + Ok(Rotation::Floating(Radians(f32::from_str(s)?))) + } + } +} -- cgit v1.2.3