1use std::{collections::HashSet, fmt::Display};
2
3use crate::{background, color::Color, length::Length, simple_props::SimpleAttribute};
4
5use super::{AttributeGetter, Style, StyleBaseState};
6
7pub(crate) trait ToAttribute {
8 fn attribute(self) -> Attribute;
9}
10
11#[derive(Hash, Eq, PartialEq)]
12pub enum Attribute {
13 AccentColor(Color),
14 FontSize(Length),
15 Top(Length),
16 Bottom(Length),
17 Right(Length),
18 Left(Length),
19 Height(Length),
20 Width(Length),
21 Margin(Length),
22 Padding(Length),
23 BackgroundColor(Color),
24 BackgroundImage(String),
25 BackgroundPositionX(background::PositionX),
26 BackgroundPositionY(background::PositionY),
27 BackgroundPosition(background::XYPosition),
28 BackgroundSize(background::Size),
29 SimpleAttribute(SimpleAttribute),
30}
31
32impl Style<StyleBaseState<()>> {
33 pub fn with_capacity(capacity: usize) -> Self {
34 Self(HashSet::with_capacity(capacity), Default::default())
35 }
36
37 pub(crate) fn into_prebase<T>(
38 self,
39 fun: AttributeGetter<T>,
40 ) -> Style<StyleBaseState<AttributeGetter<T>>> {
41 Style(self.get_attributes(), StyleBaseState(fun))
42 }
43
44 pub fn accent_color(self) -> Style<StyleBaseState<AttributeGetter<Color>>> {
45 self.into_prebase(Box::new(Attribute::AccentColor))
46 }
47
48 pub fn fontsize(self) -> Style<StyleBaseState<AttributeGetter<Length>>> {
49 self.into_prebase(Box::new(Attribute::FontSize))
50 }
51
52 pub fn margin(self) -> Style<StyleBaseState<AttributeGetter<Length>>> {
53 self.into_prebase(Box::new(Attribute::Margin))
54 }
55
56 pub fn padding(self) -> Style<StyleBaseState<AttributeGetter<Length>>> {
57 self.into_prebase(Box::new(Attribute::Padding))
58 }
59
60 pub fn bottom(self) -> Style<StyleBaseState<AttributeGetter<Length>>> {
61 self.into_prebase(Box::new(Attribute::Bottom))
62 }
63
64 pub fn height(self) -> Style<StyleBaseState<AttributeGetter<Length>>> {
65 self.into_prebase(Box::new(Attribute::Height))
66 }
67
68 pub fn width(self) -> Style<StyleBaseState<AttributeGetter<Length>>> {
69 self.into_prebase(Box::new(Attribute::Width))
70 }
71}
72
73impl Display for Style<StyleBaseState<()>> {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 let result = self
76 .0
77 .iter()
78 .map(|x| match x {
79 Attribute::AccentColor(x) => format!("accent-color:{x};"),
80 Attribute::FontSize(x) => format!("font-size:{x};"),
81 Attribute::Top(x) => format!("top:{x};"),
82 Attribute::Bottom(x) => format!("bottom:{x};"),
83 Attribute::Right(x) => format!("right:{x};"),
84 Attribute::Left(x) => format!("left:{x};"),
85 Attribute::Height(x) => format!("height:{x};"),
86 Attribute::Width(x) => format!("width:{x};"),
87 Attribute::Margin(x) => format!("margin:{x};"),
88 Attribute::Padding(x) => format!("padding:{x};"),
89 Attribute::BackgroundColor(x) => {
90 format!("background-color:{x};")
91 }
92 Attribute::BackgroundImage(x) => format!("background-image:url({x});"),
93 Attribute::BackgroundPosition(x) => format!("background-position:{x};"),
94 Attribute::BackgroundPositionX(x) => format!("background-position-x:{x};"),
95 Attribute::BackgroundPositionY(x) => format!("background-position-y:{x};"),
96 Attribute::BackgroundSize(x) => format!("background-size:{x};"),
97 Attribute::SimpleAttribute(x) => x.to_string(),
98 })
99 .fold(String::new(), move |acc, x| acc + &x);
100 write!(f, "{}", result)
101 }
102}