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