1#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
2pub enum Display {
3 Flex {
4 flex_direction: FlexDirection,
5 },
6 #[default]
7 Block,
8 Inline,
9 None,
10}
11
12#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
13pub enum FlexDirection {
14 Row,
15 #[default]
16 Column,
17}
18
19#[derive(Debug, Clone, PartialEq)]
20pub enum Length {
21 Px(f32),
22 Percent(f32),
23 Vw(f32),
24 Vh(f32),
25 Auto,
26 Add(Box<Length>, Box<Length>),
28 Sub(Box<Length>, Box<Length>),
29 Mul(Box<Length>, f32),
30 Div(Box<Length>, f32),
31
32 Min(Box<Length>, Box<Length>),
33 Max(Box<Length>, Box<Length>),
34 Clamp {
35 min: Box<Length>,
36 val: Box<Length>,
37 max: Box<Length>,
38 },
39}
40
41impl Default for Length {
42 fn default() -> Self {
43 Length::Px(0.0)
44 }
45}
46
47impl Length {
48 pub fn resolve_with(
53 &self,
54 containing_block: Option<f32>,
55 viewport_width: f32,
56 viewport_height: f32,
57 ) -> Option<f32> {
58 match self {
59 Length::Auto => None,
60 Length::Px(v) => Some(*v),
61 Length::Percent(p) => containing_block.map(|cb| cb * *p / 100.0),
62 Length::Vw(v) => Some(viewport_width * *v / 100.0),
63 Length::Vh(v) => Some(viewport_height * *v / 100.0),
64 Length::Add(a, b) => Some(
65 a.resolve_with(containing_block, viewport_width, viewport_height)?
66 + b.resolve_with(containing_block, viewport_width, viewport_height)?,
67 ),
68 Length::Sub(a, b) => Some(
69 a.resolve_with(containing_block, viewport_width, viewport_height)?
70 - b.resolve_with(containing_block, viewport_width, viewport_height)?,
71 ),
72 Length::Mul(a, n) => {
73 Some(a.resolve_with(containing_block, viewport_width, viewport_height)? * n)
74 }
75 Length::Div(a, n) => {
76 if *n == 0.0 {
77 None
78 } else {
79 Some(a.resolve_with(containing_block, viewport_width, viewport_height)? / n)
80 }
81 }
82 Length::Min(a, b) => Some(
83 a.resolve_with(containing_block, viewport_width, viewport_height)?
84 .min(b.resolve_with(containing_block, viewport_width, viewport_height)?),
85 ),
86 Length::Max(a, b) => Some(
87 a.resolve_with(containing_block, viewport_width, viewport_height)?
88 .max(b.resolve_with(containing_block, viewport_width, viewport_height)?),
89 ),
90 Length::Clamp { min, val, max } => {
91 let v = val.resolve_with(containing_block, viewport_width, viewport_height)?;
92 let min_v = min.resolve_with(containing_block, viewport_width, viewport_height)?;
93 let max_v = max.resolve_with(containing_block, viewport_width, viewport_height)?;
94
95 Some(v.clamp(min_v, max_v))
96 }
97 }
98 }
99}
100
101#[derive(Debug, Clone, PartialEq)]
102pub struct ItemStyle {
103 pub flex_grow: f32,
104 pub flex_shrink: f32,
105 pub flex_basis: Length,
106 pub align_self: Option<AlignItems>,
107}
108
109impl Default for ItemStyle {
110 fn default() -> Self {
111 ItemStyle {
112 flex_grow: 0.0,
113 flex_shrink: 1.0,
114 flex_basis: Length::Auto,
115 align_self: None,
116 }
117 }
118}
119
120#[derive(Debug, Clone, PartialEq)]
121pub struct SizeStyle {
122 pub width: Length,
123 pub height: Length,
124 pub min_width: Length,
125 pub max_width: Length,
126 pub min_height: Length,
127 pub max_height: Length,
128}
129
130impl Default for SizeStyle {
131 fn default() -> Self {
132 SizeStyle {
133 width: Length::Auto,
134 height: Length::Auto,
135 min_width: Length::Auto,
136 max_width: Length::Auto,
137 min_height: Length::Auto,
138 max_height: Length::Auto,
139 }
140 }
141}
142
143#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
144pub enum BoxSizing {
145 #[default]
146 ContentBox,
147 BorderBox,
148}
149
150#[derive(Debug, Clone, Default, PartialEq)]
151pub struct Spacing {
152 pub margin_top: Length,
153 pub margin_bottom: Length,
154 pub margin_left: Length,
155 pub margin_right: Length,
156
157 pub border_top: Length,
158 pub border_bottom: Length,
159 pub border_left: Length,
160 pub border_right: Length,
161
162 pub padding_top: Length,
163 pub padding_bottom: Length,
164 pub padding_left: Length,
165 pub padding_right: Length,
166}
167
168#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
169pub enum JustifyContent {
170 #[default]
171 Start,
172 Center,
173 End,
174 SpaceBetween,
175 SpaceAround,
176 SpaceEvenly,
177}
178
179#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
180pub enum AlignItems {
181 Start,
182 Center,
183 End,
184 #[default]
185 Stretch,
186}
187
188#[derive(Debug, Clone, Default, PartialEq)]
189pub struct Style {
190 pub display: Display,
191 pub item_style: ItemStyle,
192 pub size: SizeStyle,
193 pub box_sizing: BoxSizing,
194 pub spacing: Spacing,
195
196 pub justify_content: JustifyContent,
197 pub align_items: AlignItems,
198 pub column_gap: Length,
199 pub row_gap: Length,
200}
201
202use std::ops::{Add, Sub};
205
206impl Add for Length {
207 type Output = Length;
208
209 fn add(self, rhs: Length) -> Length {
210 Length::Add(Box::new(self), Box::new(rhs))
211 }
212}
213
214impl Sub for Length {
215 type Output = Length;
216
217 fn sub(self, rhs: Length) -> Length {
218 Length::Sub(Box::new(self), Box::new(rhs))
219 }
220}