1use std::{collections::HashSet, hash::Hash};
2
3use crate::utilities::align_self::align_self_css;
4use crate::utilities::bg_img::bg_img_css;
5use crate::utilities::flex::*;
6use crate::utilities::font_size::font_size_css;
7use crate::utilities::h::h_css;
8use crate::utilities::hide::*;
9use crate::utilities::line_height::line_height_css;
10use crate::utilities::p::*;
11use crate::utilities::p_child::*;
12use crate::utilities::p_recursive::*;
13use crate::utilities::ratio::ratio_css;
14use crate::utilities::relative::relative_css;
15use crate::utilities::w::w_css;
16use crate::utilities::z_index::z_index_css;
17
18#[derive(Debug, PartialEq, Hash, Eq)]
19pub enum LayoutClass<'a> {
20 MaxWidth(&'a str),
22 MinCellWidth(&'a str),
23 MinCols(&'a str),
24 MaxCols(&'a str),
25 Recursive,
26 Reverse,
27 Screen,
28 TwinWidth,
29 NoWrap,
30 HideBar,
31 AndText,
32 Grow,
33 Gap(&'a str),
34 GapX(&'a str),
35 GapY(&'a str),
36 GapDir(&'a str),
37 Scale(&'a str),
38 Align(&'a str),
39 Position(&'a str),
40 Top(&'a str),
41 Bottom(&'a str),
42 Left(&'a str),
43 Right(&'a str),
44 Height(&'a str),
45 ItemWidth(&'a str),
46 MinHeight(&'a str),
47 MaxHeight(&'a str),
48 SideWidth(&'a str),
49 Side(&'a str),
50 ContentMin(&'a str),
51 Threshold(&'a str),
52 Limit(&'a str),
53 KeepP,
54 KeepPL,
55 KeepPR,
56 KeepCenter,
57 Shrink,
58 Template(&'a str),
59 Col(&'a str),
60 Row(&'a str),
61
62 AlignSelf(&'a str),
64 BgImg(&'a str),
65 FlexBasis(&'a str),
66 FlexGrow(&'a str),
67 FlexShrink(&'a str),
68 FontSize(&'a str),
69 H(&'a str),
70 HideOver(&'a str),
71 HideUnder(&'a str),
72 LineHeight(&'a str),
73 Justify(&'a str),
74 P(&'a str),
75 PT(&'a str),
76 PB(&'a str),
77 PL(&'a str),
78 PR(&'a str),
79 PX(&'a str),
80 PY(&'a str),
81 PChild(&'a str),
82 PTChild(&'a str),
83 PBChild(&'a str),
84 PLChild(&'a str),
85 PRChild(&'a str),
86 PXChild(&'a str),
87 PYChild(&'a str),
88 PRecursive(&'a str),
89 PTRecursive(&'a str),
90 PBRecursive(&'a str),
91 PLRecursive(&'a str),
92 PRRecursive(&'a str),
93 PXRecursive(&'a str),
94 PYRecursive(&'a str),
95 Ratio(&'a str),
96 Relative,
97 W(&'a str),
98 ZIndex(&'a str),
99}
100
101impl<'a> TryFrom<&'a str> for LayoutClass<'a> {
102 type Error = ();
103
104 fn try_from(input: &'a str) -> Result<LayoutClass<'a>, Self::Error> {
105 let colon_index = input.find(':');
106 let (class_name, class_value) = if let Some(i) = colon_index {
107 if input.len() <= i + 1 {
110 return Err(());
111 }
112 (Some(&input[..i]), Some(&input[i + 1..]))
113 } else {
114 (Some(&input[..]), None)
115 };
116 match (class_name, class_value) {
117 (Some(class), Some(value)) => match class {
119 "max-width" => Ok(LayoutClass::MaxWidth(value)),
120 "min-cell-width" => Ok(LayoutClass::MinCellWidth(value)),
121 "min-cols" => Ok(LayoutClass::MinCols(value)),
122 "max-cols" => Ok(LayoutClass::MaxCols(value)),
123 "gap" => Ok(LayoutClass::Gap(value)),
124 "gap-x" => Ok(LayoutClass::GapX(value)),
125 "gap-y" => Ok(LayoutClass::GapY(value)),
126 "gap-dir" => Ok(LayoutClass::GapDir(value)),
127 "scale" => Ok(LayoutClass::Scale(value)),
128 "align" => Ok(LayoutClass::Align(value)),
129 "position" => Ok(LayoutClass::Position(value)),
130 "top" => Ok(LayoutClass::Top(value)),
131 "bottom" => Ok(LayoutClass::Bottom(value)),
132 "left" => Ok(LayoutClass::Left(value)),
133 "right" => Ok(LayoutClass::Right(value)),
134 "height" => Ok(LayoutClass::Height(value)),
135 "item-width" => Ok(LayoutClass::ItemWidth(value)),
136 "min-height" => Ok(LayoutClass::MinHeight(value)),
137 "max-height" => Ok(LayoutClass::MaxHeight(value)),
138 "side" => Ok(LayoutClass::Side(value)),
139 "side-width" => Ok(LayoutClass::SideWidth(value)),
140 "content-min" => Ok(LayoutClass::ContentMin(value)),
141 "threshold" => Ok(LayoutClass::Threshold(value)),
142 "template" => Ok(LayoutClass::Template(value)),
143 "limit" => Ok(LayoutClass::Limit(value)),
144
145 "align-self" => Ok(LayoutClass::AlignSelf(value)),
146 "bg-img" => Ok(LayoutClass::BgImg(value)),
147 "flex-basis" => Ok(LayoutClass::FlexBasis(value)),
148 "flex-grow" => Ok(LayoutClass::FlexGrow(value)),
149 "flex-shrink" => Ok(LayoutClass::FlexShrink(value)),
150 "font-size" => Ok(LayoutClass::FontSize(value)),
151 "h" => Ok(LayoutClass::H(value)),
152 "hide-over" => Ok(LayoutClass::HideOver(value)),
153 "hide-under" => Ok(LayoutClass::HideUnder(value)),
154 "line-height" => Ok(LayoutClass::LineHeight(value)),
155 "p" => Ok(LayoutClass::P(value)),
156 "pt" => Ok(LayoutClass::PT(value)),
157 "pb" => Ok(LayoutClass::PB(value)),
158 "pl" => Ok(LayoutClass::PL(value)),
159 "pr" => Ok(LayoutClass::PR(value)),
160 "px" => Ok(LayoutClass::PX(value)),
161 "py" => Ok(LayoutClass::PY(value)),
162 "p-child" => Ok(LayoutClass::PChild(value)),
163 "pt-child" => Ok(LayoutClass::PTChild(value)),
164 "pb-child" => Ok(LayoutClass::PBChild(value)),
165 "pl-child" => Ok(LayoutClass::PLChild(value)),
166 "pr-child" => Ok(LayoutClass::PRChild(value)),
167 "px-child" => Ok(LayoutClass::PXChild(value)),
168 "py-child" => Ok(LayoutClass::PYChild(value)),
169 "p-recursive" => Ok(LayoutClass::PRecursive(value)),
170 "pt-recursive" => Ok(LayoutClass::PTRecursive(value)),
171 "pb-recursive" => Ok(LayoutClass::PBRecursive(value)),
172 "pl-recursive" => Ok(LayoutClass::PLRecursive(value)),
173 "pr-recursive" => Ok(LayoutClass::PRRecursive(value)),
174 "px-recursive" => Ok(LayoutClass::PXRecursive(value)),
175 "py-recursive" => Ok(LayoutClass::PYRecursive(value)),
176
177 "justify" => Ok(LayoutClass::Justify(value)),
178
179 "ratio" => Ok(LayoutClass::Ratio(value)),
180 "w" => Ok(LayoutClass::W(value)),
181 "z-index" => Ok(LayoutClass::ZIndex(value)),
182
183 c if c.starts_with("row-") => Ok(LayoutClass::Row(input)),
186 c if c.starts_with("col-") => Ok(LayoutClass::Col(input)),
187
188 _ => Err(()),
189 },
190 (Some(class), None) => match class {
192 "recursive" => Ok(LayoutClass::Recursive),
193 "reverse" => Ok(LayoutClass::Reverse),
194 "screen" => Ok(LayoutClass::Screen),
195 "twin-width" => Ok(LayoutClass::TwinWidth),
196 "nowrap" => Ok(LayoutClass::NoWrap),
197 "hide-bar" => Ok(LayoutClass::HideBar),
198 "relative" => Ok(LayoutClass::Relative),
199 "grow" => Ok(LayoutClass::Grow),
200 "keep-p" => Ok(LayoutClass::KeepP),
201 "keep-pl" => Ok(LayoutClass::KeepPL),
202 "keep-pr" => Ok(LayoutClass::KeepPR),
203 "keep-center" => Ok(LayoutClass::KeepCenter),
204 "shrink" => Ok(LayoutClass::Shrink),
205 "and-text" => Ok(LayoutClass::AndText),
206 _ => Err(()),
207 },
208 _ => Err(()),
209 }
210 }
211}
212
213impl<'a> LayoutClass<'a> {
214 pub fn insert_css(self, harmonic_ratio: f64, set: &mut HashSet<String>) {
219 match self {
220 Self::AlignSelf(value) => align_self_css(value, set),
221 Self::BgImg(value) => bg_img_css(value, set),
222 Self::FlexBasis(value) => flex_basis_css(value, set),
223 Self::FlexGrow(value) => flex_grow_css(value, set),
224 Self::FlexShrink(value) => flex_shrink_css(value, set),
225 Self::FontSize(value) => font_size_css(value, harmonic_ratio, set),
226 Self::H(value) => h_css(value, harmonic_ratio, set),
227 Self::HideOver(value) => hide_over_css(value, set),
228 Self::HideUnder(value) => hide_under_css(value, set),
229 Self::LineHeight(value) => line_height_css(value, set),
230 Self::P(value) => p_css(value, harmonic_ratio, set),
231 Self::PT(value) => pt_css(value, harmonic_ratio, set),
232 Self::PB(value) => pb_css(value, harmonic_ratio, set),
233 Self::PL(value) => pl_css(value, harmonic_ratio, set),
234 Self::PR(value) => pr_css(value, harmonic_ratio, set),
235 Self::PX(value) => px_css(value, harmonic_ratio, set),
236 Self::PY(value) => py_css(value, harmonic_ratio, set),
237 Self::PChild(value) => p_child_css(value, harmonic_ratio, set),
238 Self::PTChild(value) => pt_child_css(value, harmonic_ratio, set),
239 Self::PBChild(value) => pb_child_css(value, harmonic_ratio, set),
240 Self::PLChild(value) => pl_child_css(value, harmonic_ratio, set),
241 Self::PRChild(value) => pr_child_css(value, harmonic_ratio, set),
242 Self::PXChild(value) => px_child_css(value, harmonic_ratio, set),
243 Self::PYChild(value) => py_child_css(value, harmonic_ratio, set),
244 Self::PRecursive(value) => p_recursive_css(value, harmonic_ratio, set),
245 Self::PTRecursive(value) => pt_recursive_css(value, harmonic_ratio, set),
246 Self::PBRecursive(value) => pb_recursive_css(value, harmonic_ratio, set),
247 Self::PLRecursive(value) => pl_recursive_css(value, harmonic_ratio, set),
248 Self::PRRecursive(value) => pr_recursive_css(value, harmonic_ratio, set),
249 Self::PXRecursive(value) => px_recursive_css(value, harmonic_ratio, set),
250 Self::PYRecursive(value) => py_recursive_css(value, harmonic_ratio, set),
251 Self::Ratio(value) => ratio_css(value, set),
252 Self::Relative => relative_css(set),
253 Self::W(value) => w_css(value, harmonic_ratio, set),
254 Self::ZIndex(value) => z_index_css(value, set),
255 _ => {}
256 }
257 }
258}
259
260#[cfg(test)]
261mod tests {
262 use super::*;
263
264 #[test]
265 fn create_layout_class_for_rows_area() {
266 let layout_class = "col-3:440px";
267 let cols_variant = LayoutClass::try_from(layout_class);
268 assert_eq!(cols_variant, Ok(LayoutClass::Col("col-3:440px")));
270 }
271
272 #[test]
273 fn create_layout_class_when_value_expected_but_no_set_with_colon() {
274 let layout_class = "max-width:";
275 let max_width_variant = LayoutClass::try_from(layout_class);
276 assert_eq!(max_width_variant, Err(()));
277 }
278
279 #[test]
280 fn create_layout_class_when_value_expected_but_no_set_without_colon() {
281 let layout_class = "max-width";
282 let max_width_variant = LayoutClass::try_from(layout_class);
283 assert_eq!(max_width_variant, Err(()));
284 }
285
286 #[test]
287 fn create_layout_class_from_text() {
288 let layout_class = "max-width:440px";
289 let max_width_variant = LayoutClass::try_from(layout_class);
290 assert_eq!(max_width_variant, Ok(LayoutClass::MaxWidth("440px")));
291 }
292}