diff options
Diffstat (limited to 'src/values/padding.rs')
| -rw-r--r-- | src/values/padding.rs | 214 |
1 files changed, 172 insertions, 42 deletions
diff --git a/src/values/padding.rs b/src/values/padding.rs index 01e333b..12880a3 100644 --- a/src/values/padding.rs +++ b/src/values/padding.rs @@ -3,67 +3,197 @@ use std::str::FromStr; use iced::Padding; -use super::ValueFromStr; +use super::Value; -#[derive(Debug, thiserror::Error)] -pub enum PaddingError { - #[error("wrong number of values")] - WrongNumberOfValues, +#[derive(Debug, thiserror::Error, Clone, PartialEq)] +pub enum ParsePaddingError { + #[error("wrong number of values: {0}, expected 1-4")] + WrongNumberOfValues(usize), #[error("float parsing error: {0}")] ParseFloatError(ParseFloatError), #[error("missing bracket")] MissingBracket, - #[error("empty string given")] + #[error("cannot parse padding from empty string")] Empty, } -impl From<ParseFloatError> for PaddingError { +impl From<ParseFloatError> for ParsePaddingError { fn from(value: ParseFloatError) -> Self { Self::ParseFloatError(value) } } -impl ValueFromStr for Padding { - type Err = PaddingError; +impl Value for Padding { + type Err = ParsePaddingError; - fn value_from_str(s: &str) -> Result<Self, Self::Err> { + fn from_str(s: &str) -> Result<Self, Self::Err> { if s.is_empty() { - return Err(PaddingError::Empty); + return Err(ParsePaddingError::Empty); } - let values = s - .strip_prefix('[') - .ok_or(PaddingError::MissingBracket)? - .strip_suffix(']') - .ok_or(PaddingError::MissingBracket)? - .split(',') - .map(|n| f32::from_str(n)) - .collect::<Result<Vec<_>, _>>()?; - match values.len() { - 1 => Ok(Padding { - top: values[0], - right: values[0], - bottom: values[0], - left: values[0], + + if !s.contains(['[', ',', ']']) { + let value = f32::from_str(s)?; + Ok(Padding { + top: value, + right: value, + bottom: value, + left: value, + }) + } else { + let values = s + .strip_prefix('[') + .and_then(|s| s.strip_suffix(']')) + .ok_or(ParsePaddingError::MissingBracket)? + .split(',') + .map(str::trim) + .map(f32::from_str) + .collect::<Result<Vec<_>, _>>()?; + + 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], + }), + other => Err(ParsePaddingError::WrongNumberOfValues(other)), + } + } + } + + fn to_string(&self) -> String { + format!( + "[{}, {}, {}, {}]", + self.top, self.right, self.bottom, self.left + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_parse_single_value() { + assert_eq!( + Padding::from_str("[1.5]"), + Ok(Padding { + top: 1.5, + right: 1.5, + bottom: 1.5, + left: 1.5, }), - 2 => Ok(Padding { - top: values[0], - right: values[1], - bottom: values[0], - left: values[1], + ) + } + + #[test] + fn can_parse_single_value_without_brackets() { + assert_eq!( + Padding::from_str("1.5"), + Ok(Padding { + top: 1.5, + right: 1.5, + bottom: 1.5, + left: 1.5, }), - 3 => Ok(Padding { - top: values[0], - right: values[1], - bottom: values[2], - left: values[1], + ) + } + + #[test] + fn can_parse_two_values() { + assert_eq!( + Padding::from_str("[3.2, 6.7]"), + Ok(Padding { + top: 3.2, + right: 6.7, + bottom: 3.2, + left: 6.7, }), - 4 => Ok(Padding { - top: values[0], - right: values[1], - bottom: values[2], - left: values[3], + ) + } + + #[test] + fn can_parse_three_values() { + assert_eq!( + Padding::from_str("[4.8, 8.1,5.9]"), + Ok(Padding { + top: 4.8, + right: 8.1, + bottom: 5.9, + left: 8.1, }), - _ => Err(PaddingError::WrongNumberOfValues), - } + ) + } + + #[test] + fn can_parse_four_values() { + assert_eq!( + Padding::from_str("[35.4,74.6 ,53.1, 25.0]"), + Ok(Padding { + top: 35.4, + right: 74.6, + bottom: 53.1, + left: 25.0, + }), + ) + } + + #[test] + fn cant_parse_five_values() { + assert_eq!( + Padding::from_str("[1,2,3,4,5]"), + Err(ParsePaddingError::WrongNumberOfValues(5)), + ) + } + + #[test] + fn cant_parse_invalid_floats() { + assert_eq!( + Padding::from_str("[1f,2,3,4]"), + Err(ParsePaddingError::ParseFloatError( + f32::from_str("1f").expect_err("") + )) + ) + } + + #[test] + fn cant_parse_with_missing_bracket() { + assert_eq!( + Padding::from_str("1,2,3,4,5]"), + Err(ParsePaddingError::MissingBracket) + ); + + assert_eq!( + Padding::from_str("[1,2,3,4,5"), + Err(ParsePaddingError::MissingBracket) + ); + + assert_eq!( + Padding::from_str("1,2,3,4,5"), + Err(ParsePaddingError::MissingBracket) + ) + } + + #[test] + fn cant_parse_empty_string() { + assert_eq!(Padding::from_str(""), Err(ParsePaddingError::Empty)) } } |
