classnames/classes/
el_class.rs

1use crate::classes::{AttrClass, DuoClass, OptionClass};
2use crate::Class;
3use ::std::borrow::Cow;
4use ::std::convert::From;
5use ::std::fmt;
6use ::std::ops::Add;
7
8#[derive(Copy, Clone, PartialEq, Debug)]
9pub struct ElClass<N, C: fmt::Display + Clone = &'static str> {
10    parent: N,
11    class: C,
12}
13
14impl<N> Class for ElClass<N> where N: fmt::Display + Sized + PartialEq + Clone {}
15
16impl<N: Sized + fmt::Display + Copy> ElClass<N> {
17    pub(crate) fn new<'a>(parent: N, class: &'a str) -> ElClass<N, &'a str> {
18        ElClass { parent, class }
19    }
20
21    pub fn el(self, class: &'static str) -> ElClass<Self> {
22        ElClass {
23            parent: self,
24            class,
25        }
26    }
27
28    pub fn attr(self, attr: &'static str) -> AttrClass<Self> {
29        AttrClass::new(self).attr(attr)
30    }
31
32    pub fn maybe_attr(self, attr: &'static str, is_set: bool) -> AttrClass<Self> {
33        AttrClass::new(self).maybe_attr(attr, is_set)
34    }
35}
36
37impl<N, O> Add<O> for ElClass<N>
38where
39    N: Class,
40    O: Class,
41{
42    type Output = DuoClass<Self, O>;
43
44    fn add(self, other: O) -> Self::Output {
45        DuoClass::new(self, other)
46    }
47}
48
49impl<'s, N> Add<&'s str> for ElClass<N>
50where
51    N: Class,
52{
53    type Output = DuoClass<Self, &'s str>;
54
55    fn add(self, other: &'s str) -> Self::Output {
56        DuoClass::new(self, other)
57    }
58}
59
60impl<N, O> Add<Option<O>> for ElClass<N>
61where
62    N: Class,
63    O: Class,
64{
65    type Output = DuoClass<Self, OptionClass<O>>;
66
67    fn add(self, other: Option<O>) -> Self::Output {
68        DuoClass::new(self, OptionClass::new(other))
69    }
70}
71
72impl<N: fmt::Display> fmt::Display for ElClass<N> {
73    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74        write!(f, "{}__{}", self.parent, self.class)
75    }
76}
77
78impl<'a, N: fmt::Display> From<ElClass<N>> for Cow<'a, str> {
79    fn from(class: ElClass<N>) -> Self {
80        class.to_string().into()
81    }
82}
83
84impl<'a, N: fmt::Display> From<ElClass<N>> for String {
85    fn from(class: ElClass<N>) -> Self {
86        class.to_string()
87    }
88}
89
90#[cfg(test)]
91mod maybe_attr {
92    use crate::*;
93
94    #[test]
95    fn is_should_set_attr_if_is_set() {
96        let el = classname("mr-component").el("child");
97        assert_eq!(
98            "mr-component__child mr-component__child--red",
99            el.maybe_attr("red", true).to_string()
100        )
101    }
102
103    #[test]
104    fn is_should_not_set_attr_if_is_set_is_false() {
105        let el = classname("mr-component").el("child");
106        assert_eq!(
107            "mr-component__child",
108            el.maybe_attr("red", false).to_string()
109        )
110    }
111
112    #[test]
113    fn is_should_still_set_more_attr_after_false_maybe_attr() {
114        let el = classname("mr-component").el("child");
115        assert_eq!(
116            "mr-component__child mr-component__child--blue",
117            el.maybe_attr("red", false).attr("blue").to_string()
118        )
119    }
120}