1use crate::value::{
2    layouts::{
3        FlexBasis, FlexDirection, FlexPosition, FlexWrap, GridAuto, GridFlow, GridTemplate,
4        MultiColumnLineStyle,
5    },
6    BorderRadius, BorderStyle, BoxBorder, BoxShadow, Color, FontFamily, FontStyle, Position,
7    TextAlign, Unit, VecUnit,
8};
9
10pub fn camel_snake(camel: &str) -> String {
11    let mut res = "".to_string();
12    camel.trim().chars().enumerate().for_each(|(n, c)| {
13        if n > 0 && c.is_ascii_uppercase() {
14            res.push_str("-");
15        }
16        res.push(c);
17    });
18
19    res.to_lowercase()
20}
21
22macro_rules! construct_style {
23    ($trait:ident, $fn_name:tt) => {
24
25    };
26    (
27        [$(($ns:ident, $ty:tt, $nf:tt, $ndoc:expr),)*],
28        [$(($ss:ident, $sf:tt, $sdoc:expr),)*]
29    ) => {
30        #[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
32        pub enum Style {
33            $(
34                #[doc=$ndoc]
35                $ns($ty),
36            )*
37            $(
38                #[doc=$sdoc]
39                $ss($ss),
40            )*
41        }
42
43        impl Style {
44            pub fn to_css(&self) -> String {
46                match self {
47                    $(
48                        Style::$ns(v) => format!(
49                            "{}: {}",
50                            camel_snake(stringify!($ns)),
51                            v.to_string()
52                        ),
53                    )*
54                    $(
55                        Style::$ss(v) => format!(
56                            "{}: {}",
57                            camel_snake(stringify!($ss)),
58                            v.to_string()
59                        ),
60                    )*
61                }
62            }
63        }
64
65        $(
66            impl From<$ss> for Style {
67                fn from(s: $ss) -> Style {
68                    Style::$ss(s)
69                }
70            }
71        )*
72
73        pub mod traits {
75            use crate::{Style, Node};
76            $(
77                #[doc=$ndoc]
78                pub trait $ns {
79                    #[doc=$ndoc]
80                    fn $nf(self, value: super::$ty) -> Node;
81                }
82
83                impl<T> $ns for T
84                where
85                    T: Into<Node>,
86                {
87                    fn $nf(self, value: super::$ty) -> Node {
88                        let mut node: Node = self.into();
89                        node.style.push(Style::$ns(value));
90                        node
91                    }
92                }
93            )*
94        }
95    };
96}
97
98construct_style! {[
99    (Width, Unit, width, "Box Width"),
101    (Height, Unit, height, "Box Height"),
102    (MaxWidth, Unit, max_width, "Box Max Width"),
103    (MaxHeight, Unit, max_height, "Box Max Height"),
104    (OutlineWidth, Unit, outline_width, "Box Outline Width"),
105    (Top, Unit, top, "Box Top"),
106    (Right, Unit, right, "Box Right"),
107    (Bottom, Unit, bottom, "Box Bottom"),
108    (Left, Unit, left, "Box Left"),
109    (Padding, VecUnit, padding, "Box Padding"),
110    (PaddingTop, Unit, padding_top, "Padding Top"),
111    (PaddingRight, Unit, padding_right, "Padding right"),
112    (PaddingBottom, Unit, padding_bottom, "Padding Bottom"),
113    (PaddingLeft, Unit, padding_left, "Padding left"),
114    (Margin, VecUnit, margin, "Box Margin"),
115    (MarginTop, Unit, margin_top, "Margin Top"),
116    (MarginRight, Unit, margin_right, "Margin right"),
117    (MarginBottom, Unit, margin_bottom, "Margin Bottom"),
118    (MarginLeft, Unit, margin_left, "Margin left"),
119
120    (BorderTop, BoxBorder, border_top, "Border Top"),
122    (BorderRight, BoxBorder, border_right, "Border Right"),
123    (BorderBottom, BoxBorder, border_bottom, "Border Bottom"),
124    (BorderLeft, BoxBorder, border_left, "Border Left"),
125    (Border, BoxBorder, border, "Border Border"),
126
127    (FontWeight, Unit, font_weight, "Font Weight Style"),
129    (FontSize, Unit, font_size, "Font Size Style"),
130    (FontStretch, Unit, font_stretch, "Font Stretch Style"),
131    (LineHeight, Unit, line_hegiht, "Line Height Style"),
132
133    (Color, Color, color, "Custom Color"),
135    (BackgroundColor, Color, background_color, "Custom Color"),
136
137    (AlignItems, FlexPosition, align_items, "AlignItem Style"),
139    (JustifyContent, FlexPosition, justify_content, "AlignItem Style"),
140    (FlexGrow, Unit, flex_glow, "FlexGrow Style"),
141    (Order, Unit, order, "FlexOrder Style"),
142
143    (GridAutoColumns, GridAuto, grid_auto_columns, "GridAutoColumn Style"),
145    (GridAutoRows, GridAuto, grid_auto_rows, "GridAutoColumn Style"),
146    (GridAutoFlow, GridFlow, grid_auto_flow, "GridAutoFlow Style"),
147    (GridColumnGap, Unit, grid_column_gap, "GridColumnGap Style"),
148    (GridRowGap, Unit, grid_row_rap, "GridColumnGap Style"),
149    (GridTemplateColumns, GridTemplate, grid_template_columns, "GridTemplateColumns Style"),
150    (GridTemplateRows, GridTemplate, grid_tempalte_row, "GridTemplateRow Style"),
151
152    (ColumnCount, Unit, column_count, "ColumnCount Style"),
154    (ColumnGap, Unit, column_gap, "ColumnGap Style"),
155    (ColumnRuleColor, Color, column_rule_color, "ColumnRuleColor Style"),
156    (ColumnRuleStyle, MultiColumnLineStyle, column_rule_style, "ColumnRuleStyle Style"),
157], [
158    (FlexBasis, flex_basis, "FlexBasis style"),
160    (FlexDirection, flex_direction, "FlexDirection style"),
161    (FlexPosition, flex_position, "FlexPosition style"),
162    (FlexWrap, flex_wrap, "Flex Wrap Style"),
163    (BorderStyle, border_style, "Border Style"),
164
165    (GridAuto, grid_auto, "Grid Auto Style"),
167    (GridFlow, grid_flow, "Grid Flow Style"),
168    (GridTemplate, grid_template, "Grid Template Style"),
169
170    (FontStyle, font_style, "Font Style"),
172    (FontFamily, font_family, "Font Family"),
173
174    (TextAlign, text_align, "Text Align"),
176
177    (BoxShadow, box_shadow, "Box Shadow"),
179    (Position, position, "Box Position"),
180
181    (BorderRadius, box_radius, "Border Radius"),
183]}