1use crate::class::{ClassName, HasClasses};
2use alloc::fmt;
3use smallvec::SmallVec;
4
5#[derive(Debug, Default, Clone, Hash)]
15pub struct Classes {
16 classes: SmallVec<[ClassName; 5]>,
17}
18
19impl Classes {
20 #[inline]
24 pub(crate) fn add_if(&mut self, class: impl Into<ClassName>, condition: bool) {
25 if condition {
26 self.set(class, true);
27 }
28 }
29
30 #[inline]
32 pub(crate) fn set(&mut self, class: impl Into<ClassName>, present: bool) {
33 let class = class.into();
34 self.classes.retain(|existing| existing != &class);
36 if present {
37 self.classes.push(class);
38 }
39 }
40
41 #[inline]
45 pub(crate) fn extend(&mut self, classes: impl IntoIterator<Item = impl Into<ClassName>>) {
46 for class in classes {
47 self.set(class, true);
48 }
49 }
50
51 #[inline]
53 pub fn iter(&self) -> core::slice::Iter<'_, ClassName> {
54 self.classes.iter()
55 }
56
57 #[inline]
59 pub fn as_slice(&self) -> &[ClassName] {
60 self.classes.as_slice()
61 }
62}
63
64impl IntoIterator for Classes {
65 type Item = ClassName;
66 type IntoIter = smallvec::IntoIter<[ClassName; 5]>;
67
68 #[inline]
69 fn into_iter(self) -> Self::IntoIter {
70 self.classes.into_iter()
71 }
72}
73
74impl<'a> IntoIterator for &'a Classes {
75 type Item = &'a ClassName;
76 type IntoIter = core::slice::Iter<'a, ClassName>;
77
78 #[inline]
79 fn into_iter(self) -> Self::IntoIter {
80 self.classes.iter()
81 }
82}
83
84impl HasClasses for Classes {
85 fn classes(&self) -> &Classes {
86 self
87 }
88
89 fn classes_mut(&mut self) -> &mut Classes {
90 self
91 }
92}
93
94impl core::fmt::Display for Classes {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 for (i, class) in self.classes.iter().enumerate() {
97 if i > 0 {
98 f.write_str(" ")?;
99 }
100 f.write_str(class.as_str())?;
101 }
102 Ok(())
103 }
104}