From e96f3830f19ed63ae8b43f8ce33f824237b34d82 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 15 Jul 2020 23:49:10 +0200 Subject: =?UTF-8?q?Use=20FromStr=20trait=20and=20formatting=20=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/syntax/expr.rs | 56 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 20 deletions(-) (limited to 'src/syntax/expr.rs') 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 { + fn from_str(hex_str: &str) -> Result { 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, -- cgit v1.2.3