diff --git a/src/class.rs b/src/class.rs index 1dfa52d..7159c7d 100644 --- a/src/class.rs +++ b/src/class.rs @@ -1,4 +1,4 @@ -use crate::Zephyr; +use crate::{Zephyr, ZephyrError}; #[derive(PartialEq, Debug)] pub(crate) struct Class<'a> { @@ -56,7 +56,7 @@ impl<'a> Class<'a> { r } - pub(crate) fn generate(&self, z: &Zephyr) -> Result { + pub(crate) fn generate(&self, z: &Zephyr) -> Result { let name = z .names .get(self.name) @@ -84,7 +84,7 @@ impl<'a> Class<'a> { } else if let Some(v) = z.rules.get(name) { Ok(format!("{selector}{{{v}}}")) } else { - Err("{name} is not a no-variable rule, and no variables were provided") + Err(ZephyrError::ValueMissing) } } } diff --git a/src/lib.rs b/src/lib.rs index 36300ca..8b114c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,14 @@ pub struct Zephyr { /// Value -> Rules pub type SpecialRule = Box String>; +#[derive(PartialEq, Debug)] +pub enum ZephyrError { + /// the provided rule has invalid braces (single braces, or in incorrect order `..}...{..`) + InvalidBraces, + /// the provided rule isn't a no-variable rule, but no variables were provided + ValueMissing, +} + impl Zephyr { /// builds a `Zephyr` with the default ruleset pub fn new() -> Self { @@ -80,15 +88,15 @@ impl Zephyr { } }) // we ignore errors - .flat_map(|c| self.generate_class(c).ok().flatten()) + .flat_map(|c| self.generate_class(c).ok()) .collect::>() .join("") } /// this one returns an error if parsing or generating fails - // TODO add an error type - pub fn generate_class(&self, class: &str) -> Result, &'static str> { - parse_class(class).map(|c| c.generate(self)).transpose() + pub fn generate_class(&self, class: &str) -> Result { + let c = parse_class(class)?; + c.generate(self) } } diff --git a/src/parse.rs b/src/parse.rs index 2012905..5145709 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,7 +1,6 @@ -use crate::class::Class; +use crate::{class::Class, ZephyrError}; -// TODO return error -pub(crate) fn parse_class<'a>(original: &'a str) -> Option> { +pub(crate) fn parse_class<'a>(original: &'a str) -> Result, ZephyrError> { // this code is kinda repetitive but idk let (class, pseudo) = if let Some((class, pseudo)) = original.split_once('$') { @@ -17,7 +16,7 @@ pub(crate) fn parse_class<'a>(original: &'a str) -> Option> { class[p + 1..].split(',').collect() }; - return Some(Class { + return Ok(Class { name: &class[0..p], value: None, modifiers: mods.into(), @@ -35,7 +34,7 @@ pub(crate) fn parse_class<'a>(original: &'a str) -> Option> { class[end + 1..].split(',').collect() }; - return Some(Class { + return Ok(Class { name: &class[0..start], value: Some(&class[start + 1..end]), modifiers: mods.into(), @@ -46,9 +45,9 @@ pub(crate) fn parse_class<'a>(original: &'a str) -> Option> { } // go to [...] case (None, None) => {} + // braces do not form a valid block _ => { - // TODO return an error here - return None; + return Err(ZephyrError::InvalidBraces); } }; @@ -60,7 +59,7 @@ pub(crate) fn parse_class<'a>(original: &'a str) -> Option> { class[end + 1..].split(',').collect() }; - return Some(Class { + return Ok(Class { name: &class[0..start], value: Some(&class[start + 1..end]), modifiers: mods.into(), @@ -70,7 +69,7 @@ pub(crate) fn parse_class<'a>(original: &'a str) -> Option> { }); } _ => { - return Some(Class { + return Ok(Class { name: &class[0..], value: None, modifiers: vec![].into(), @@ -96,7 +95,7 @@ mod tests { ) { assert_eq!( parse_class(class), - Some(Class { + Ok(Class { name, value, modifiers: modifiers.into(), @@ -112,7 +111,7 @@ mod tests { ) { assert_eq!( parse_class(class), - Some(Class { + Ok(Class { name, value, modifiers: modifiers.into(),