styling/
attribute.rs

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}