azul_css/props/style/
azul_exclusion.rs1use std::num::ParseFloatError;
4
5#[cfg(feature = "parser")]
6use crate::macros::*;
7use crate::{
8 corety::AzString,
9 format_rust_code::FormatAsRustCode,
10 props::{
11 basic::{length::parse_float_value, FloatValue},
12 formatter::{FormatAsCssValue, PrintAsCssValue},
13 },
14};
15
16#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
28#[repr(C)]
29pub struct StyleExclusionMargin {
30 pub inner: FloatValue,
31}
32
33impl Default for StyleExclusionMargin {
34 fn default() -> Self {
35 Self {
36 inner: FloatValue::const_new(0),
37 }
38 }
39}
40
41impl StyleExclusionMargin {
42 pub fn is_initial(&self) -> bool {
43 self.inner.number == 0
44 }
45}
46
47impl PrintAsCssValue for StyleExclusionMargin {
48 fn print_as_css_value(&self) -> String {
49 format!("{}", self.inner.get())
50 }
51}
52
53impl FormatAsCssValue for StyleExclusionMargin {
54 fn format_as_css_value(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
55 write!(f, "{}", self.inner.get())
56 }
57}
58
59impl FormatAsRustCode for StyleExclusionMargin {
60 fn format_as_rust_code(&self, _tabs: usize) -> String {
61 format!(
62 "StyleExclusionMargin {{ inner: FloatValue::const_new({}) }}",
63 self.inner.get()
64 )
65 }
66}
67
68#[cfg(feature = "parser")]
69#[derive(Clone, PartialEq)]
70pub enum StyleExclusionMarginParseError {
71 FloatValue(ParseFloatError),
72}
73
74#[cfg(feature = "parser")]
75impl_debug_as_display!(StyleExclusionMarginParseError);
76
77#[cfg(feature = "parser")]
78impl_display! { StyleExclusionMarginParseError, {
79 FloatValue(e) => format!("Invalid -azul-exclusion-margin value: {}", e),
80}}
81
82#[cfg(feature = "parser")]
83impl_from!(ParseFloatError, StyleExclusionMarginParseError::FloatValue);
84
85#[cfg(feature = "parser")]
86#[derive(Debug, Clone, PartialEq)]
87pub enum StyleExclusionMarginParseErrorOwned {
88 FloatValue(String),
89}
90
91#[cfg(feature = "parser")]
92impl StyleExclusionMarginParseError {
93 pub fn to_contained(&self) -> StyleExclusionMarginParseErrorOwned {
94 match self {
95 Self::FloatValue(e) => {
96 StyleExclusionMarginParseErrorOwned::FloatValue(format!("{}", e))
97 }
98 }
99 }
100}
101
102#[cfg(feature = "parser")]
103impl StyleExclusionMarginParseErrorOwned {
104 pub fn to_shared<'a>(&'a self) -> StyleExclusionMarginParseError {
105 match self {
106 Self::FloatValue(e) => {
107 StyleExclusionMarginParseError::FloatValue(e.parse::<f32>().unwrap_err())
109 }
110 }
111 }
112}
113
114#[cfg(feature = "parser")]
115pub fn parse_style_exclusion_margin(
116 input: &str,
117) -> Result<StyleExclusionMargin, StyleExclusionMarginParseError> {
118 parse_float_value(input)
119 .map(|inner| StyleExclusionMargin { inner })
120 .map_err(|e| StyleExclusionMarginParseError::FloatValue(e))
121}
122
123#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
135#[repr(C)]
136pub struct StyleHyphenationLanguage {
137 pub inner: AzString,
138}
139
140impl Default for StyleHyphenationLanguage {
141 fn default() -> Self {
142 Self {
143 inner: AzString::from_const_str("en-US"),
144 }
145 }
146}
147
148impl StyleHyphenationLanguage {
149 pub const fn is_initial(&self) -> bool {
150 false
152 }
153}
154
155impl PrintAsCssValue for StyleHyphenationLanguage {
156 fn print_as_css_value(&self) -> String {
157 format!("\"{}\"", self.inner.as_str())
158 }
159}
160
161impl FormatAsCssValue for StyleHyphenationLanguage {
162 fn format_as_css_value(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
163 write!(f, "\"{}\"", self.inner.as_str())
164 }
165}
166
167impl FormatAsRustCode for StyleHyphenationLanguage {
168 fn format_as_rust_code(&self, _tabs: usize) -> String {
169 format!(
170 "StyleHyphenationLanguage {{ inner: AzString::from_const_str(\"{}\") }}",
171 self.inner.as_str()
172 )
173 }
174}
175
176#[cfg(feature = "parser")]
177#[derive(Clone, PartialEq)]
178pub enum StyleHyphenationLanguageParseError {
179 InvalidString(String),
180}
181
182#[cfg(feature = "parser")]
183impl_debug_as_display!(StyleHyphenationLanguageParseError);
184
185#[cfg(feature = "parser")]
186impl_display! { StyleHyphenationLanguageParseError, {
187 InvalidString(e) => format!("Invalid -azul-hyphenation-language value: {}", e),
188}}
189
190#[cfg(feature = "parser")]
191#[derive(Debug, Clone, PartialEq)]
192pub enum StyleHyphenationLanguageParseErrorOwned {
193 InvalidString(String),
194}
195
196#[cfg(feature = "parser")]
197impl StyleHyphenationLanguageParseError {
198 pub fn to_contained(&self) -> StyleHyphenationLanguageParseErrorOwned {
199 match self {
200 Self::InvalidString(e) => {
201 StyleHyphenationLanguageParseErrorOwned::InvalidString(e.clone())
202 }
203 }
204 }
205}
206
207#[cfg(feature = "parser")]
208impl StyleHyphenationLanguageParseErrorOwned {
209 pub fn to_shared<'a>(&'a self) -> StyleHyphenationLanguageParseError {
210 match self {
211 Self::InvalidString(e) => StyleHyphenationLanguageParseError::InvalidString(e.clone()),
212 }
213 }
214}
215
216#[cfg(feature = "parser")]
217pub fn parse_style_hyphenation_language(
218 input: &str,
219) -> Result<StyleHyphenationLanguage, StyleHyphenationLanguageParseError> {
220 let trimmed = input.trim();
222 let unquoted = if (trimmed.starts_with('"') && trimmed.ends_with('"'))
223 || (trimmed.starts_with('\'') && trimmed.ends_with('\''))
224 {
225 &trimmed[1..trimmed.len() - 1]
226 } else {
227 trimmed
228 };
229
230 Ok(StyleHyphenationLanguage {
231 inner: AzString::from_string(unquoted.to_string()),
232 })
233}
234
235#[cfg(test)]
236mod tests {
237 use super::*;
238
239 #[test]
240 fn test_parse_exclusion_margin() {
241 let margin = parse_style_exclusion_margin("10.5").unwrap();
242 assert_eq!(margin.inner.get(), 10.5);
243
244 let margin = parse_style_exclusion_margin("0").unwrap();
245 assert_eq!(margin.inner.get(), 0.0);
246 }
247
248 #[test]
249 fn test_parse_hyphenation_language() {
250 let lang = parse_style_hyphenation_language("\"en-US\"").unwrap();
251 assert_eq!(lang.inner.as_str(), "en-US");
252
253 let lang = parse_style_hyphenation_language("'de-DE'").unwrap();
254 assert_eq!(lang.inner.as_str(), "de-DE");
255
256 let lang = parse_style_hyphenation_language("fr-FR").unwrap();
257 assert_eq!(lang.inner.as_str(), "fr-FR");
258 }
259
260 #[test]
261 fn test_exclusion_margin_default() {
262 let margin = StyleExclusionMargin::default();
263 assert_eq!(margin.inner.get(), 0.0);
264 assert!(margin.is_initial());
265 }
266
267 #[test]
268 fn test_hyphenation_language_default() {
269 let lang = StyleHyphenationLanguage::default();
270 assert_eq!(lang.inner.as_str(), "en-US");
271 }
272}