ferrum_email_core/
style.rs1use crate::color::Color;
7use crate::spacing::Spacing;
8use crate::types::*;
9
10#[derive(Debug, Clone, Default, PartialEq)]
14pub struct Style {
15 pub font_family: Option<FontFamily>,
16 pub font_size: Option<Px>,
17 pub font_weight: Option<FontWeight>,
18 pub color: Option<Color>,
19 pub background_color: Option<Color>,
20 pub padding: Option<Spacing>,
21 pub margin: Option<Spacing>,
22 pub border_radius: Option<Px>,
23 pub width: Option<SizeValue>,
24 pub max_width: Option<SizeValue>,
25 pub min_width: Option<SizeValue>,
26 pub height: Option<SizeValue>,
27 pub text_align: Option<TextAlign>,
28 pub vertical_align: Option<VerticalAlign>,
29 pub line_height: Option<LineHeight>,
30 pub display: Option<Display>,
31 pub border: Option<Border>,
32 pub border_bottom: Option<Border>,
33 pub border_top: Option<Border>,
34 pub text_decoration: Option<TextDecoration>,
35 pub letter_spacing: Option<Px>,
36 pub word_spacing: Option<Px>,
37}
38
39#[derive(Debug, Clone, PartialEq)]
41pub struct Border {
42 pub width: Px,
43 pub style: BorderStyle,
44 pub color: Color,
45}
46
47impl Border {
48 pub fn new(width: Px, style: BorderStyle, color: Color) -> Self {
49 Border {
50 width,
51 style,
52 color,
53 }
54 }
55
56 pub fn solid(width: Px, color: Color) -> Self {
57 Border::new(width, BorderStyle::Solid, color)
58 }
59}
60
61impl std::fmt::Display for Border {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 write!(f, "{} {} {}", self.width, self.style, self.color)
64 }
65}
66
67impl Style {
68 pub fn new() -> Self {
70 Self::default()
71 }
72
73 pub fn to_css(&self) -> Option<String> {
77 let mut parts = Vec::new();
78
79 if let Some(ref ff) = self.font_family {
80 parts.push(format!("font-family:{ff}"));
81 }
82 if let Some(ref fs) = self.font_size {
83 parts.push(format!("font-size:{fs}"));
84 }
85 if let Some(ref fw) = self.font_weight {
86 parts.push(format!("font-weight:{fw}"));
87 }
88 if let Some(ref c) = self.color {
89 parts.push(format!("color:{c}"));
90 }
91 if let Some(ref bg) = self.background_color {
92 parts.push(format!("background-color:{bg}"));
93 }
94 if let Some(ref p) = self.padding {
95 parts.push(format!("padding:{p}"));
96 }
97 if let Some(ref m) = self.margin {
98 parts.push(format!("margin:{m}"));
99 }
100 if let Some(ref br) = self.border_radius {
101 parts.push(format!("border-radius:{br}"));
102 }
103 if let Some(ref w) = self.width {
104 parts.push(format!("width:{w}"));
105 }
106 if let Some(ref mw) = self.max_width {
107 parts.push(format!("max-width:{mw}"));
108 }
109 if let Some(ref mw) = self.min_width {
110 parts.push(format!("min-width:{mw}"));
111 }
112 if let Some(ref h) = self.height {
113 parts.push(format!("height:{h}"));
114 }
115 if let Some(ref ta) = self.text_align {
116 parts.push(format!("text-align:{ta}"));
117 }
118 if let Some(ref va) = self.vertical_align {
119 parts.push(format!("vertical-align:{va}"));
120 }
121 if let Some(ref lh) = self.line_height {
122 parts.push(format!("line-height:{lh}"));
123 }
124 if let Some(ref d) = self.display {
125 parts.push(format!("display:{d}"));
126 }
127 if let Some(ref b) = self.border {
128 parts.push(format!("border:{b}"));
129 }
130 if let Some(ref b) = self.border_bottom {
131 parts.push(format!("border-bottom:{b}"));
132 }
133 if let Some(ref b) = self.border_top {
134 parts.push(format!("border-top:{b}"));
135 }
136 if let Some(ref td) = self.text_decoration {
137 parts.push(format!("text-decoration:{td}"));
138 }
139 if let Some(ref ls) = self.letter_spacing {
140 parts.push(format!("letter-spacing:{ls}"));
141 }
142 if let Some(ref ws) = self.word_spacing {
143 parts.push(format!("word-spacing:{ws}"));
144 }
145
146 if parts.is_empty() {
147 None
148 } else {
149 Some(parts.join(";"))
150 }
151 }
152
153 pub fn merge(&mut self, other: &Style) {
155 macro_rules! merge_field {
156 ($field:ident) => {
157 if other.$field.is_some() {
158 self.$field = other.$field.clone();
159 }
160 };
161 }
162 merge_field!(font_family);
163 merge_field!(font_size);
164 merge_field!(font_weight);
165 merge_field!(color);
166 merge_field!(background_color);
167 merge_field!(padding);
168 merge_field!(margin);
169 merge_field!(border_radius);
170 merge_field!(width);
171 merge_field!(max_width);
172 merge_field!(min_width);
173 merge_field!(height);
174 merge_field!(text_align);
175 merge_field!(vertical_align);
176 merge_field!(line_height);
177 merge_field!(display);
178 merge_field!(border);
179 merge_field!(border_bottom);
180 merge_field!(border_top);
181 merge_field!(text_decoration);
182 merge_field!(letter_spacing);
183 merge_field!(word_spacing);
184 }
185}