vertigo/css/
css_structs.rs

1use std::ops::{Add, AddAssign};
2
3/// Css chunk, represented either as static or dynamic string.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum CssGroup {
6    // &str - can be used as id using which we can find particular rule
7    CssStatic { value: &'static str },
8    // string in this case, is a key to hashmap with the class name
9    CssDynamic { value: String },
10    CssMedia { query: String, rules: Vec<String> },
11}
12
13/// CSS styles definition for use in DOM.
14///
15/// Consists of a vector of css chunks which can be extended.
16///
17/// ```rust
18/// use vertigo::{Css, dom};
19///
20/// let blue_text = Css::str("color: blue");
21/// let black_background = Css::str("background: black");
22///
23/// let my_styles = Css::str("
24///     font-family: courier;
25///     font-size: 160%
26/// ")
27///     .extend(blue_text)
28///     .extend(black_background);
29///
30/// let element = dom! { <div css={my_styles} /> };
31/// ```
32#[derive(Debug, Default, Clone, PartialEq, Eq)]
33pub struct Css {
34    pub groups: Vec<CssGroup>,
35}
36
37impl Css {
38    pub fn str(value: &'static str) -> Self {
39        Self {
40            groups: vec![CssGroup::CssStatic { value }],
41        }
42    }
43
44    pub fn string(value: String) -> Self {
45        Self {
46            groups: vec![CssGroup::CssDynamic { value }],
47        }
48    }
49
50    #[must_use]
51    pub fn push_str(mut self, value: &'static str) -> Self {
52        self.groups.push(CssGroup::CssStatic { value });
53        self
54    }
55
56    pub fn push_string(&mut self, value: String) {
57        self.groups.push(CssGroup::CssDynamic { value })
58    }
59
60    /// Extend current Css returning new one.
61    #[must_use]
62    pub fn extend(mut self, new_css: Self) -> Self {
63        for item in new_css.groups {
64            self.groups.push(item);
65        }
66
67        self
68    }
69
70    /// Extend current Css with other Css in-place.
71    pub fn extend_inplace(&mut self, new_css: Self) {
72        for item in new_css.groups {
73            self.groups.push(item);
74        }
75    }
76}
77
78impl Add for Css {
79    type Output = Self;
80
81    fn add(self, rhs: Self) -> Self::Output {
82        self.extend(rhs)
83    }
84}
85
86impl Add for &Css {
87    type Output = Css;
88
89    fn add(self, rhs: Self) -> Self::Output {
90        self.clone().extend(rhs.clone())
91    }
92}
93
94impl Add<&Self> for Css {
95    type Output = Self;
96
97    fn add(self, rhs: &Self) -> Self::Output {
98        self.extend(rhs.clone())
99    }
100}
101
102impl Add<Css> for &Css {
103    type Output = Css;
104
105    fn add(self, rhs: Css) -> Self::Output {
106        self.clone().extend(rhs)
107    }
108}
109
110impl AddAssign for Css {
111    fn add_assign(&mut self, other: Self) {
112        self.extend_inplace(other);
113    }
114}
115
116impl AddAssign<&Self> for Css {
117    fn add_assign(&mut self, other: &Self) {
118        self.extend_inplace(other.clone());
119    }
120}
121
122impl AddAssign<&Css> for &mut Css {
123    fn add_assign(&mut self, other: &Css) {
124        self.extend_inplace(other.clone());
125    }
126}