1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5pub struct ContainerSystem {
6 pub max_widths: Vec<ContainerMaxWidth>,
7 pub paddings: Vec<f64>,
8 pub margins: Vec<f64>,
9 pub centers: Vec<bool>,
10}
11
12impl Default for ContainerSystem {
13 fn default() -> Self {
14 Self {
15 max_widths: [
16 ContainerMaxWidth::Small,
17 ContainerMaxWidth::Medium,
18 ContainerMaxWidth::Large,
19 ContainerMaxWidth::ExtraLarge,
20 ContainerMaxWidth::Fluid,
21 ]
22 .to_vec(),
23 paddings: [16.0, 24.0, 32.0, 48.0].to_vec(),
24 margins: [0.0, 16.0, 24.0, 32.0, 48.0].to_vec(),
25 centers: [true, false].to_vec(),
26 }
27 }
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
32pub enum ContainerMaxWidth {
33 Small,
34 Medium,
35 Large,
36 ExtraLarge,
37 Fluid,
38}
39
40impl ContainerMaxWidth {
41 pub fn as_str(&self) -> &'static str {
42 match self {
43 ContainerMaxWidth::Small => "sm",
44 ContainerMaxWidth::Medium => "md",
45 ContainerMaxWidth::Large => "lg",
46 ContainerMaxWidth::ExtraLarge => "xl",
47 ContainerMaxWidth::Fluid => "fluid",
48 }
49 }
50
51 pub fn max_width(&self) -> Option<f64> {
52 match self {
53 ContainerMaxWidth::Small => Some(640.0),
54 ContainerMaxWidth::Medium => Some(768.0),
55 ContainerMaxWidth::Large => Some(1024.0),
56 ContainerMaxWidth::ExtraLarge => Some(1280.0),
57 ContainerMaxWidth::Fluid => None,
58 }
59 }
60}
61
62#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
64pub struct GridSystem {
65 pub columns: u32,
66 pub gutters: Vec<f64>,
67 pub gaps: Vec<f64>,
68 pub alignments: Vec<GridAlignment>,
69}
70
71impl Default for GridSystem {
72 fn default() -> Self {
73 Self {
74 columns: 12,
75 gutters: [16.0, 24.0, 32.0, 48.0].to_vec(),
76 gaps: [8.0, 16.0, 24.0, 32.0, 48.0].to_vec(),
77 alignments: [
78 GridAlignment::Start,
79 GridAlignment::Center,
80 GridAlignment::End,
81 GridAlignment::Stretch,
82 GridAlignment::SpaceBetween,
83 GridAlignment::SpaceAround,
84 GridAlignment::SpaceEvenly,
85 ]
86 .to_vec(),
87 }
88 }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
93pub enum GridAlignment {
94 Start,
95 Center,
96 End,
97 Stretch,
98 SpaceBetween,
99 SpaceAround,
100 SpaceEvenly,
101}
102
103impl GridAlignment {
104 pub fn as_str(&self) -> &'static str {
105 match self {
106 GridAlignment::Start => "start",
107 GridAlignment::Center => "center",
108 GridAlignment::End => "end",
109 GridAlignment::Stretch => "stretch",
110 GridAlignment::SpaceBetween => "space-between",
111 GridAlignment::SpaceAround => "space-around",
112 GridAlignment::SpaceEvenly => "space-evenly",
113 }
114 }
115}
116
117#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
119pub struct FlexboxSystem {
120 pub directions: Vec<FlexDirection>,
121 pub wraps: Vec<FlexWrap>,
122 pub justifications: Vec<JustifyContent>,
123 pub alignments: Vec<AlignItems>,
124 pub grows: Vec<f64>,
125 pub shrinks: Vec<f64>,
126}
127
128impl Default for FlexboxSystem {
129 fn default() -> Self {
130 Self {
131 directions: [
132 FlexDirection::Row,
133 FlexDirection::RowReverse,
134 FlexDirection::Column,
135 FlexDirection::ColumnReverse,
136 ]
137 .to_vec(),
138 wraps: [FlexWrap::Nowrap, FlexWrap::Wrap, FlexWrap::WrapReverse].to_vec(),
139 justifications: [
140 JustifyContent::Start,
141 JustifyContent::End,
142 JustifyContent::Center,
143 JustifyContent::SpaceBetween,
144 JustifyContent::SpaceAround,
145 JustifyContent::SpaceEvenly,
146 ]
147 .to_vec(),
148 alignments: [
149 AlignItems::Start,
150 AlignItems::End,
151 AlignItems::Center,
152 AlignItems::Baseline,
153 AlignItems::Stretch,
154 ]
155 .to_vec(),
156 grows: [0.0, 1.0, 2.0, 3.0].to_vec(),
157 shrinks: [0.0, 1.0, 2.0, 3.0].to_vec(),
158 }
159 }
160}
161
162#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
164pub enum FlexDirection {
165 Row,
166 RowReverse,
167 Column,
168 ColumnReverse,
169}
170
171impl FlexDirection {
172 pub fn as_str(&self) -> &'static str {
173 match self {
174 FlexDirection::Row => "row",
175 FlexDirection::RowReverse => "row-reverse",
176 FlexDirection::Column => "column",
177 FlexDirection::ColumnReverse => "column-reverse",
178 }
179 }
180}
181
182#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
184pub enum FlexWrap {
185 Nowrap,
186 Wrap,
187 WrapReverse,
188}
189
190impl FlexWrap {
191 pub fn as_str(&self) -> &'static str {
192 match self {
193 FlexWrap::Nowrap => "nowrap",
194 FlexWrap::Wrap => "wrap",
195 FlexWrap::WrapReverse => "wrap-reverse",
196 }
197 }
198}
199
200#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
202pub enum JustifyContent {
203 Start,
204 End,
205 Center,
206 SpaceBetween,
207 SpaceAround,
208 SpaceEvenly,
209}
210
211impl JustifyContent {
212 pub fn as_str(&self) -> &'static str {
213 match self {
214 JustifyContent::Start => "start",
215 JustifyContent::End => "end",
216 JustifyContent::Center => "center",
217 JustifyContent::SpaceBetween => "space-between",
218 JustifyContent::SpaceAround => "space-around",
219 JustifyContent::SpaceEvenly => "space-evenly",
220 }
221 }
222}
223
224#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
226pub enum AlignItems {
227 Start,
228 End,
229 Center,
230 Baseline,
231 Stretch,
232}
233
234impl AlignItems {
235 pub fn as_str(&self) -> &'static str {
236 match self {
237 AlignItems::Start => "start",
238 AlignItems::End => "end",
239 AlignItems::Center => "center",
240 AlignItems::Baseline => "baseline",
241 AlignItems::Stretch => "stretch",
242 }
243 }
244}
245
246#[cfg(test)]
247mod container_tests {
248 use super::*;
249
250 #[test]
251 fn test_container_system_default() {
252 let containers = ContainerSystem::default();
253 assert!(containers.max_widths.contains(&ContainerMaxWidth::Small));
254 assert!(containers.max_widths.contains(&ContainerMaxWidth::Medium));
255 assert!(containers.max_widths.contains(&ContainerMaxWidth::Large));
256 assert!(containers
257 .max_widths
258 .contains(&ContainerMaxWidth::ExtraLarge));
259 assert!(containers.max_widths.contains(&ContainerMaxWidth::Fluid));
260 assert!(containers.paddings.contains(&16.0));
261 assert!(containers.paddings.contains(&24.0));
262 assert!(containers.paddings.contains(&32.0));
263 assert!(containers.paddings.contains(&48.0));
264 assert!(containers.margins.contains(&0.0));
265 assert!(containers.margins.contains(&16.0));
266 assert!(containers.margins.contains(&24.0));
267 assert!(containers.margins.contains(&32.0));
268 assert!(containers.margins.contains(&48.0));
269 assert!(containers.centers.contains(&true));
270 assert!(containers.centers.contains(&false));
271 }
272
273 #[test]
274 fn test_container_max_width_enum() {
275 assert_eq!(ContainerMaxWidth::Small.as_str(), "sm");
276 assert_eq!(ContainerMaxWidth::Medium.as_str(), "md");
277 assert_eq!(ContainerMaxWidth::Large.as_str(), "lg");
278 assert_eq!(ContainerMaxWidth::ExtraLarge.as_str(), "xl");
279 assert_eq!(ContainerMaxWidth::Fluid.as_str(), "fluid");
280 }
281
282 #[test]
283 fn test_container_max_width_values() {
284 assert_eq!(ContainerMaxWidth::Small.max_width(), Some(640.0));
285 assert_eq!(ContainerMaxWidth::Medium.max_width(), Some(768.0));
286 assert_eq!(ContainerMaxWidth::Large.max_width(), Some(1024.0));
287 assert_eq!(ContainerMaxWidth::ExtraLarge.max_width(), Some(1280.0));
288 assert_eq!(ContainerMaxWidth::Fluid.max_width(), None);
289 }
290
291 #[test]
292 fn test_grid_system_default() {
293 let grid = GridSystem::default();
294 assert_eq!(grid.columns, 12);
295 assert!(grid.gutters.contains(&16.0));
296 assert!(grid.gutters.contains(&24.0));
297 assert!(grid.gutters.contains(&32.0));
298 assert!(grid.gutters.contains(&48.0));
299 assert!(grid.gaps.contains(&8.0));
300 assert!(grid.gaps.contains(&16.0));
301 assert!(grid.gaps.contains(&24.0));
302 assert!(grid.gaps.contains(&32.0));
303 assert!(grid.gaps.contains(&48.0));
304 assert!(grid.alignments.contains(&GridAlignment::Start));
305 assert!(grid.alignments.contains(&GridAlignment::Center));
306 assert!(grid.alignments.contains(&GridAlignment::End));
307 assert!(grid.alignments.contains(&GridAlignment::Stretch));
308 }
309
310 #[test]
311 fn test_grid_alignment_enum() {
312 assert_eq!(GridAlignment::Start.as_str(), "start");
313 assert_eq!(GridAlignment::Center.as_str(), "center");
314 assert_eq!(GridAlignment::End.as_str(), "end");
315 assert_eq!(GridAlignment::Stretch.as_str(), "stretch");
316 assert_eq!(GridAlignment::SpaceBetween.as_str(), "space-between");
317 assert_eq!(GridAlignment::SpaceAround.as_str(), "space-around");
318 assert_eq!(GridAlignment::SpaceEvenly.as_str(), "space-evenly");
319 }
320
321 #[test]
322 fn test_flexbox_system_default() {
323 let flexbox = FlexboxSystem::default();
324 assert!(flexbox.directions.contains(&FlexDirection::Row));
325 assert!(flexbox.directions.contains(&FlexDirection::RowReverse));
326 assert!(flexbox.directions.contains(&FlexDirection::Column));
327 assert!(flexbox.directions.contains(&FlexDirection::ColumnReverse));
328 assert!(flexbox.wraps.contains(&FlexWrap::Nowrap));
329 assert!(flexbox.wraps.contains(&FlexWrap::Wrap));
330 assert!(flexbox.wraps.contains(&FlexWrap::WrapReverse));
331 assert!(flexbox.justifications.contains(&JustifyContent::Start));
332 assert!(flexbox.justifications.contains(&JustifyContent::End));
333 assert!(flexbox.justifications.contains(&JustifyContent::Center));
334 assert!(flexbox.alignments.contains(&AlignItems::Start));
335 assert!(flexbox.alignments.contains(&AlignItems::End));
336 assert!(flexbox.alignments.contains(&AlignItems::Center));
337 assert!(flexbox.grows.contains(&0.0));
338 assert!(flexbox.grows.contains(&1.0));
339 assert!(flexbox.shrinks.contains(&0.0));
340 assert!(flexbox.shrinks.contains(&1.0));
341 }
342
343 #[test]
344 fn test_flex_direction_enum() {
345 assert_eq!(FlexDirection::Row.as_str(), "row");
346 assert_eq!(FlexDirection::RowReverse.as_str(), "row-reverse");
347 assert_eq!(FlexDirection::Column.as_str(), "column");
348 assert_eq!(FlexDirection::ColumnReverse.as_str(), "column-reverse");
349 }
350
351 #[test]
352 fn test_flex_wrap_enum() {
353 assert_eq!(FlexWrap::Nowrap.as_str(), "nowrap");
354 assert_eq!(FlexWrap::Wrap.as_str(), "wrap");
355 assert_eq!(FlexWrap::WrapReverse.as_str(), "wrap-reverse");
356 }
357
358 #[test]
359 fn test_justify_content_enum() {
360 assert_eq!(JustifyContent::Start.as_str(), "start");
361 assert_eq!(JustifyContent::End.as_str(), "end");
362 assert_eq!(JustifyContent::Center.as_str(), "center");
363 assert_eq!(JustifyContent::SpaceBetween.as_str(), "space-between");
364 assert_eq!(JustifyContent::SpaceAround.as_str(), "space-around");
365 assert_eq!(JustifyContent::SpaceEvenly.as_str(), "space-evenly");
366 }
367
368 #[test]
369 fn test_align_items_enum() {
370 assert_eq!(AlignItems::Start.as_str(), "start");
371 assert_eq!(AlignItems::End.as_str(), "end");
372 assert_eq!(AlignItems::Center.as_str(), "center");
373 assert_eq!(AlignItems::Baseline.as_str(), "baseline");
374 assert_eq!(AlignItems::Stretch.as_str(), "stretch");
375 }
376}