textiler_core/
system_props.rs

1//! System properties are exclusive, and provide translations to "real" css properties
2
3use std::borrow::Cow;
4use std::collections::HashMap;
5
6use once_cell::sync::Lazy;
7
8use crate::theme::breakpoint::Breakpoints;
9
10/// Contains standard system properties and their translations, should only exist as a
11/// singleton instance [`SYSTEM_PROPERTIES`](SYSTEM_PROPERTIES).
12#[derive(Debug, Clone)]
13pub struct SystemProperties {
14    mappings: HashMap<String, Vec<String>>,
15}
16
17static SYSTEM_PROPS_MAP: &[(&str, &[&str])] = &[
18    ("p", &["padding"]),
19    ("pl", &["paddingLeft"]),
20    ("pr", &["paddingRight"]),
21    ("pt", &["paddingTop"]),
22    ("pb", &["paddingBottom"]),
23    ("pX", &["paddingLeft", "paddingRight"]),
24    ("pY", &["paddingTop", "paddingBottom"]),
25    ("bgcolor", &["backgroundColor"]),
26    ("bg", &["background"]),
27    ("marginX", &["margin-left", "margin-right"]),
28    ("marginY", &["margin-top", "margin-bottom"]),
29];
30
31impl SystemProperties {
32    /// Create a new system properties instance
33    fn new() -> Self {
34
35        Self {
36            mappings:
37            SYSTEM_PROPS_MAP
38            .iter()
39            .map(|(k, v): &(&str, &[&str])| {
40                (
41                    k.to_string(),
42                    v.iter().map(|s| s.to_string()).collect::<Vec<_>>(),
43                )
44            })
45            .collect(),
46        }
47    }
48}
49
50impl CssPropertyTranslator for SystemProperties {
51    fn translate<'a>(&self, query: &'a str) -> Vec<Cow<'a, str>> {
52        self.mappings
53            .get(query)
54            .map(|result| {
55                result
56                    .iter()
57                    .map(|s| Cow::<str>::Owned(s.clone()))
58                    .collect::<Vec<_>>()
59            })
60            .unwrap_or_else(move || vec![Cow::Borrowed(query)])
61    }
62}
63
64pub static SYSTEM_PROPERTIES: Lazy<SystemProperties> = Lazy::new(|| SystemProperties::new());
65
66/// attempts to translate a given css query into a modified one
67#[derive(Debug)]
68pub struct TranslationUnit {
69    props: SystemProperties,
70    bps: Breakpoints,
71}
72
73impl TranslationUnit {
74    pub fn new(bps: &Breakpoints) -> Self {
75        Self {
76            props: SYSTEM_PROPERTIES.clone(),
77            bps: bps.clone(),
78        }
79    }
80}
81
82impl CssPropertyTranslator for TranslationUnit {
83    fn translate<'a>(&self, query: &'a str) -> Vec<Cow<'a, str>> {
84        if self.props.mappings.contains_key(query) {
85            self.props.translate(query)
86        } else if let Some(breakpoint) = self.bps.get(query) {
87            vec![Cow::Owned(format!(
88                "@media (min-width: {}px)",
89                breakpoint.width()
90            ))]
91        } else {
92            vec![Cow::Borrowed(query)]
93        }
94    }
95}
96
97/// Translate a given property into something else
98pub trait CssPropertyTranslator {
99    /// Translates
100    fn translate<'a>(&self, query: &'a str) -> Vec<Cow<'a, str>>;
101}