diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-07-15 23:49:10 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-07-15 23:49:10 +0200 |
| commit | e96f3830f19ed63ae8b43f8ce33f824237b34d82 (patch) | |
| tree | 62c12d1ff134a1a89dd4565270e9b862e96f8788 /src/syntax/expr.rs | |
| parent | 1683ca87f797a6262f0a4f75bde0e23eca31798c (diff) | |
Use FromStr trait and formatting ✨
Diffstat (limited to 'src/syntax/expr.rs')
| -rw-r--r-- | src/syntax/expr.rs | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index 52efbe53..3f535729 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -3,6 +3,7 @@ use std::fmt::{self, Write, Debug, Formatter}; use std::iter::FromIterator; use std::ops::Deref; +use std::str::FromStr; use std::u8; use crate::error::Errors; @@ -141,11 +142,16 @@ impl RgbaColor { RgbaColor { r, g, b, a, healed: true } } +} + +impl FromStr for RgbaColor { + type Err = ParseColorError; + /// Constructs a new color from a hex string like `7a03c2`. /// Do not specify a leading `#`. - pub fn from_str(hex_str: &str) -> Option<RgbaColor> { + fn from_str(hex_str: &str) -> Result<RgbaColor, Self::Err> { if !hex_str.is_ascii() { - return None; + return Err(ParseColorError); } let len = hex_str.len(); @@ -154,7 +160,7 @@ impl RgbaColor { let alpha = len == 4 || len == 8; if !long && !short { - return None; + return Err(ParseColorError); } let mut values: [u8; 4] = [255; 4]; @@ -164,17 +170,16 @@ impl RgbaColor { let pos = elem * item_len; let item = &hex_str[pos..(pos+item_len)]; - values[elem] = u8::from_str_radix(item, 16).ok()?; - + values[elem] = u8::from_str_radix(item, 16) + .map_err(|_| ParseColorError)?; + if short { // Duplicate number for shorthand notation, i.e. `a` -> `aa` values[elem] += values[elem] * 16; } } - Some( - RgbaColor::new(values[0], values[1], values[2], values[3]) - ) + Ok(RgbaColor::new(values[0], values[1], values[2], values[3])) } } @@ -182,23 +187,34 @@ impl Debug for RgbaColor { fn fmt(&self, f: &mut Formatter) -> fmt::Result { if f.alternate() { f.write_str("rgba(")?; - f.write_fmt(format_args!("r: {:02}, ", self.r))?; - f.write_fmt(format_args!("g: {:02}, ", self.g))?; - f.write_fmt(format_args!("b: {:02}, ", self.b))?; - f.write_fmt(format_args!("a: {:02}", self.a))?; + write!(f, "r: {:02}, ", self.r)?; + write!(f, "g: {:02}, ", self.g)?; + write!(f, "b: {:02}, ", self.b)?; + write!(f, "a: {:02}", self.a)?; f.write_char(')')?; } else { f.write_char('#')?; - f.write_fmt(format_args!("{:02x}", self.r))?; - f.write_fmt(format_args!("{:02x}", self.g))?; - f.write_fmt(format_args!("{:02x}", self.b))?; - f.write_fmt(format_args!("{:02x}", self.a))?; + write!(f, "{:02x}", self.r)?; + write!(f, "{:02x}", self.g)?; + write!(f, "{:02x}", self.b)?; + write!(f, "{:02x}", self.a)?; } if self.healed { - f.write_fmt(format_args!(" [healed]")) - } else { - Ok(()) + f.write_fmt(format_args!(" [healed]"))?; } + Ok(()) + } +} + +/// The error returned when parsing a [`RgbaColor`] from a string fails. +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct ParseColorError; + +impl std::error::Error for ParseColorError {} + +impl fmt::Display for ParseColorError { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + f.write_str("invalid color") } } @@ -296,7 +312,7 @@ impl Debug for Tuple { /// ```typst /// hsl(93, 10, 19.4) /// ``` -#[derive(Clone, PartialEq, Debug)] +#[derive(Debug, Clone, PartialEq)] pub struct NamedTuple { /// The name of the tuple and where it is in the user source. pub name: Spanned<Ident>, |
