dioxus_class_internal/
class.rs

1use std::fmt::Display;
2use std::ops::Add;
3use dioxus::prelude::*;
4use dioxus::dioxus_core::AttributeValue;
5
6/// Class struct is just a wrapper of `Vec<String>`
7///
8/// several From<> provided for easier construction
9/// most of the time, you'll use class! proc_macro to
10/// create instance.
11///
12/// Some Add<> helper also provided, so you can define
13/// common part, and append extra values if needed.
14///
15#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
16pub struct Class(pub Vec<String>);
17
18impl Display for Class {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        write!(f, "{}", self.to_class())
21    }
22}
23
24impl Class {
25    pub const NONE: Class = Class(vec![]);
26
27    pub fn to_class(&self) -> String {
28        self.0.join(" ")
29    }
30    pub fn validate(&mut self) -> () {
31        //TODO: validate the string format for css
32        self.0.sort_unstable();
33        self.0.dedup();
34    }
35    pub fn validated(&mut self) -> Self {
36        self.validate();
37        self.to_owned()
38    }
39    pub fn append(&mut self, v: &str) -> () {
40        self.0.push(v.to_string());
41    }
42}
43
44impl IntoAttributeValue for Class {
45    fn into_value(self) -> AttributeValue {
46        AttributeValue::Text(self.to_class())
47    }
48}
49
50impl IntoAttributeValue for &Class {
51    fn into_value(self) -> AttributeValue {
52        AttributeValue::Text(self.to_class())
53    }
54}
55
56impl From<Vec<&str>> for Class {
57    fn from(v: Vec<&str>) -> Self {
58        Self(v.iter().map(|x| x.to_string()).collect::<Vec<String>>())
59    }
60}
61
62impl From<Vec<String>> for Class {
63    fn from(v: Vec<String>) -> Self {
64        Self(v)
65    }
66}
67
68impl From<&[&str]> for Class {
69    fn from(v: &[&str]) -> Self {
70        Self(v.iter().map(|x| x.to_string()).collect::<Vec<String>>())
71    }
72}
73
74impl From<&[String]> for Class {
75    fn from(v: &[String]) -> Self {
76        Self(v.to_vec())
77    }
78}
79
80impl Add<&str> for Class {
81    type Output = Self;
82
83    fn add(self, rhs: &str) -> Self::Output {
84        let mut result = self.clone();
85        result.append(rhs);
86        result.validated()
87    }
88}
89
90impl Add<String> for Class {
91    type Output = Self;
92
93    fn add(self, rhs: String) -> Self::Output {
94        let mut result = self.clone();
95        result.append(&rhs);
96        result.validated()
97    }
98}
99
100impl Add<Vec<&str>> for Class {
101    type Output = Self;
102
103    fn add(self, rhs: Vec<&str>) -> Self::Output {
104        let mut result = self.clone();
105        for part in rhs {
106            result.append(part);
107        }
108        result.validated()
109    }
110}
111
112impl Add<Vec<String>> for Class {
113    type Output = Self;
114
115    fn add(self, rhs: Vec<String>) -> Self::Output {
116        let mut result = self.clone();
117        for part in rhs {
118            result.append(&part);
119        }
120        result.validated()
121    }
122}
123
124impl Add<Class> for Class {
125    type Output = Self;
126
127    fn add(self, rhs: Class) -> Self::Output {
128        let mut result = self.clone();
129        for part in rhs.0 {
130            result.append(&part);
131        }
132        result.validated()
133    }
134}
135
136impl Add<&Class> for Class {
137    type Output = Self;
138
139    fn add(self, rhs: &Class) -> Self::Output {
140        let mut result = self.clone();
141        for part in rhs.0.iter() {
142            result.append(&part);
143        }
144        result.validated()
145    }
146}
147
148impl Add<Option<&str>> for Class {
149    type Output = Self;
150
151    fn add(self, rhs: Option<&str>) -> Self::Output {
152        match rhs {
153            Some(rhs) => self + rhs,
154            None => self,
155        }
156    }
157}
158
159impl Add<Option<String>> for Class {
160    type Output = Self;
161
162    fn add(self, rhs: Option<String>) -> Self::Output {
163        match rhs {
164            Some(rhs) => self + rhs,
165            None => self,
166        }
167    }
168}
169
170impl Add<Option<Vec<&str>>> for Class {
171    type Output = Self;
172
173    fn add(self, rhs: Option<Vec<&str>>) -> Self::Output {
174        match rhs {
175            Some(rhs) => self + rhs,
176            None => self,
177        }
178    }
179}
180
181impl Add<Option<Vec<String>>> for Class {
182    type Output = Self;
183
184    fn add(self, rhs: Option<Vec<String>>) -> Self::Output {
185        match rhs {
186            Some(rhs) => self + rhs,
187            None => self,
188        }
189    }
190}
191
192impl Add<Option<Class>> for Class {
193    type Output = Self;
194
195    fn add(self, rhs: Option<Class>) -> Self::Output {
196        match rhs {
197            Some(rhs) => self + rhs,
198            None => self,
199        }
200    }
201}
202
203impl Add<Option<&Class>> for Class {
204    type Output = Self;
205
206    fn add(self, rhs: Option<&Class>) -> Self::Output {
207        match rhs {
208            Some(rhs) => self + rhs,
209            None => self,
210        }
211    }
212}
213
214impl Add<&Option<&Class>> for Class {
215    type Output = Self;
216
217    #[allow(suspicious_double_ref_op)]
218    fn add(self, rhs: &Option<&Class>) -> Self::Output {
219        match rhs {
220            Some(rhs) => self + rhs.clone(),
221            None => self,
222        }
223    }
224}