implement special classes

This commit is contained in:
annieversary 2022-07-06 12:34:49 +01:00
parent 092898fa7f
commit 5ad1f8b90d
3 changed files with 65 additions and 2 deletions

View File

@ -62,7 +62,13 @@ impl<'a> Class<'a> {
if let Some(val) = self.value { if let Some(val) = self.value {
let val = z.values.get(val).map(AsRef::as_ref).unwrap_or(val); let val = z.values.get(val).map(AsRef::as_ref).unwrap_or(val);
if let Some(fun) = z.specials.get(name) {
let v = fun(val);
Ok(format!("{selector} {{ {v} }}",))
} else {
Ok(format!("{selector} {{ {name}: {val}; }}",)) Ok(format!("{selector} {{ {name}: {val}; }}",))
}
} 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 {

View File

@ -1,5 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::SpecialRule;
pub(crate) fn default_rules() -> HashMap<String, String> { pub(crate) fn default_rules() -> HashMap<String, String> {
vec![ vec![
("flex", "display: flex;"), ("flex", "display: flex;"),
@ -70,3 +72,36 @@ pub(crate) fn default_pseudos() -> HashMap<String, String> {
.map(|(a, b)| (a.to_string(), b.to_string())) .map(|(a, b)| (a.to_string(), b.to_string()))
.collect() .collect()
} }
pub(crate) fn default_specials() -> HashMap<String, SpecialRule> {
vec![
("mx", {
fn fun<'a>(val: &'a str) -> String {
format!("margin-left: {val}; margin-right: {val};")
}
Box::new(fun) as SpecialRule
}),
("my", {
fn fun<'a>(val: &'a str) -> String {
format!("margin-top: {val}; margin-bottom: {val};")
}
Box::new(fun) as SpecialRule
}),
("px", {
fn fun<'a>(val: &'a str) -> String {
format!("padding-left: {val}; padding-right: {val};")
}
Box::new(fun) as SpecialRule
}),
("py", {
fn fun<'a>(val: &'a str) -> String {
format!("padding-top: {val}; padding-bottom: {val};")
}
Box::new(fun) as SpecialRule
}),
// TODO
]
.into_iter()
.map(|(a, b)| (a.to_string(), b))
.collect()
}

View File

@ -13,15 +13,24 @@ mod parse;
pub mod inventory; pub mod inventory;
pub struct Zephyr { pub struct Zephyr {
/// for non-value rules /// for non-value classes
pub rules: HashMap<String, String>, pub rules: HashMap<String, String>,
/// special rules. Fn(Value) -> Properties
pub specials: HashMap<String, SpecialRule>,
/// list of name short-hands
pub names: HashMap<String, String>, pub names: HashMap<String, String>,
/// list of value short-hands
pub values: HashMap<String, String>, pub values: HashMap<String, String>,
/// list of modifier short-hands
pub modifiers: HashMap<String, String>, pub modifiers: HashMap<String, String>,
/// list of pseudo-element short-hands
pub pseudos: HashMap<String, String>, pub pseudos: HashMap<String, String>,
} }
/// Value -> Rules
pub type SpecialRule = Box<dyn Fn(&str) -> String>;
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 {
@ -31,6 +40,7 @@ impl Zephyr {
values: default_values(), values: default_values(),
modifiers: default_modifiers(), modifiers: default_modifiers(),
pseudos: default_pseudos(), pseudos: default_pseudos(),
specials: default_specials(),
} }
} }
@ -42,6 +52,7 @@ impl Zephyr {
values: HashMap::new(), values: HashMap::new(),
modifiers: HashMap::new(), modifiers: HashMap::new(),
pseudos: HashMap::new(), pseudos: HashMap::new(),
specials: HashMap::new(),
} }
} }
@ -162,4 +173,15 @@ mod tests {
); );
assert_eq!(classes_separate, classes_joined); assert_eq!(classes_separate, classes_joined);
} }
#[test]
fn generate_specials_works() {
let z = Zephyr::new();
let classes = z.generate_classes(["mx[1rem]"]);
assert_eq!(
classes,
r#".mx\[1rem\] { margin-left: 1rem; margin-right: 1rem; }"#
);
}
} }