1use alloc::string::{String, ToString};
8use core::fmt;
9use crate::corety::AzString;
10
11use crate::{
12 format_rust_code::FormatAsRustCode,
13 props::{
14 basic::{
15 error::{InvalidValueErr, InvalidValueErrOwned},
16 length::{PercentageParseError, PercentageParseErrorOwned, PercentageValue},
17 pixel::{CssPixelValueParseError, CssPixelValueParseErrorOwned, PixelValue},
18 ColorU, CssDuration,
19 },
20 formatter::PrintAsCssValue,
21 macros::PixelValueTaker,
22 },
23};
24
25#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
31#[repr(C)]
32pub struct StyleTextColor {
33 pub inner: crate::props::basic::color::ColorU,
34}
35
36impl fmt::Debug for StyleTextColor {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 write!(f, "{}", self.print_as_css_value())
39 }
40}
41
42impl StyleTextColor {
43 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
44 Self {
45 inner: self.inner.interpolate(&other.inner, t),
46 }
47 }
48}
49
50impl PrintAsCssValue for StyleTextColor {
51 fn print_as_css_value(&self) -> String {
52 self.inner.to_hash()
53 }
54}
55
56#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
60#[repr(C)]
61pub enum StyleTextAlign {
62 Left,
63 Center,
64 Right,
65 Justify,
66 #[default]
67 Start,
68 End,
69}
70
71impl_option!(
72 StyleTextAlign,
73 OptionStyleTextAlign,
74 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
75);
76
77impl PrintAsCssValue for StyleTextAlign {
78 fn print_as_css_value(&self) -> String {
79 String::from(match self {
80 StyleTextAlign::Left => "left",
81 StyleTextAlign::Center => "center",
82 StyleTextAlign::Right => "right",
83 StyleTextAlign::Justify => "justify",
84 StyleTextAlign::Start => "start",
85 StyleTextAlign::End => "end",
86 })
87 }
88}
89
90#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
94#[repr(C)]
95pub struct StyleLetterSpacing {
96 pub inner: PixelValue,
97}
98
99impl fmt::Debug for StyleLetterSpacing {
100 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
101 write!(f, "{}", self.inner)
102 }
103}
104impl Default for StyleLetterSpacing {
105 fn default() -> Self {
106 Self {
107 inner: PixelValue::const_px(0),
108 }
109 }
110}
111impl_pixel_value!(StyleLetterSpacing);
112impl PixelValueTaker for StyleLetterSpacing {
113 fn from_pixel_value(inner: PixelValue) -> Self {
114 Self { inner }
115 }
116}
117impl PrintAsCssValue for StyleLetterSpacing {
118 fn print_as_css_value(&self) -> String {
119 format!("{}", self.inner)
120 }
121}
122
123#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
127#[repr(C)]
128pub struct StyleWordSpacing {
129 pub inner: PixelValue,
130}
131
132impl fmt::Debug for StyleWordSpacing {
133 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134 write!(f, "{}", self.inner)
135 }
136}
137impl Default for StyleWordSpacing {
138 fn default() -> Self {
139 Self {
140 inner: PixelValue::const_px(0),
141 }
142 }
143}
144impl_pixel_value!(StyleWordSpacing);
145impl PixelValueTaker for StyleWordSpacing {
146 fn from_pixel_value(inner: PixelValue) -> Self {
147 Self { inner }
148 }
149}
150impl PrintAsCssValue for StyleWordSpacing {
151 fn print_as_css_value(&self) -> String {
152 format!("{}", self.inner)
153 }
154}
155
156#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
160#[repr(C)]
161pub struct StyleLineHeight {
162 pub inner: PercentageValue,
163}
164impl Default for StyleLineHeight {
165 fn default() -> Self {
166 Self {
167 inner: PercentageValue::const_new(120),
168 }
169 }
170}
171impl_percentage_value!(StyleLineHeight);
172impl PrintAsCssValue for StyleLineHeight {
173 fn print_as_css_value(&self) -> String {
174 format!("{}", self.inner)
175 }
176}
177
178#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
182#[repr(C)]
183pub struct StyleTabSize {
184 pub inner: PixelValue, }
186
187impl fmt::Debug for StyleTabSize {
188 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
189 write!(f, "{}", self.inner)
190 }
191}
192impl Default for StyleTabSize {
193 fn default() -> Self {
194 Self {
195 inner: PixelValue::em(8.0),
196 }
197 }
198}
199impl_pixel_value!(StyleTabSize);
200impl PixelValueTaker for StyleTabSize {
201 fn from_pixel_value(inner: PixelValue) -> Self {
202 Self { inner }
203 }
204}
205impl PrintAsCssValue for StyleTabSize {
206 fn print_as_css_value(&self) -> String {
207 format!("{}", self.inner)
208 }
209}
210
211#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
217#[repr(C)]
218#[derive(Default)]
219pub enum StyleWhiteSpace {
220 #[default]
222 Normal,
223 Pre,
225 Nowrap,
227 PreWrap,
229 PreLine,
231 BreakSpaces,
233}
234impl_option!(
235 StyleWhiteSpace,
236 OptionStyleWhiteSpace,
237 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
238);
239impl PrintAsCssValue for StyleWhiteSpace {
240 fn print_as_css_value(&self) -> String {
241 String::from(match self {
242 StyleWhiteSpace::Normal => "normal",
243 StyleWhiteSpace::Pre => "pre",
244 StyleWhiteSpace::Nowrap => "nowrap",
245 StyleWhiteSpace::PreWrap => "pre-wrap",
246 StyleWhiteSpace::PreLine => "pre-line",
247 StyleWhiteSpace::BreakSpaces => "break-spaces",
248 })
249 }
250}
251
252#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
256#[repr(C)]
257#[derive(Default)]
258pub enum StyleHyphens {
259 None,
261 #[default]
264 Manual,
265 Auto,
269}
270impl_option!(
271 StyleHyphens,
272 OptionStyleHyphens,
273 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
274);
275impl PrintAsCssValue for StyleHyphens {
276 fn print_as_css_value(&self) -> String {
277 String::from(match self {
278 StyleHyphens::None => "none",
279 StyleHyphens::Manual => "manual",
280 StyleHyphens::Auto => "auto",
281 })
282 }
283}
284
285#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
291#[repr(C)]
292#[derive(Default)]
293pub enum StyleLineBreak {
294 #[default]
296 Auto,
297 Loose,
299 Normal,
301 Strict,
303 Anywhere,
307}
308impl_option!(
309 StyleLineBreak,
310 OptionStyleLineBreak,
311 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
312);
313impl PrintAsCssValue for StyleLineBreak {
314 fn print_as_css_value(&self) -> String {
315 String::from(match self {
316 StyleLineBreak::Auto => "auto",
317 StyleLineBreak::Loose => "loose",
318 StyleLineBreak::Normal => "normal",
319 StyleLineBreak::Strict => "strict",
320 StyleLineBreak::Anywhere => "anywhere",
321 })
322 }
323}
324
325#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
331#[repr(C)]
332#[derive(Default)]
333pub enum StyleWordBreak {
334 #[default]
336 Normal,
337 BreakAll,
339 KeepAll,
341 BreakWord,
344}
345impl_option!(
346 StyleWordBreak,
347 OptionStyleWordBreak,
348 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
349);
350impl PrintAsCssValue for StyleWordBreak {
351 fn print_as_css_value(&self) -> String {
352 String::from(match self {
353 StyleWordBreak::Normal => "normal",
354 StyleWordBreak::BreakAll => "break-all",
355 StyleWordBreak::KeepAll => "keep-all",
356 StyleWordBreak::BreakWord => "break-word",
357 })
358 }
359}
360
361#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
368#[repr(C)]
369#[derive(Default)]
370pub enum StyleOverflowWrap {
371 #[default]
373 Normal,
374 Anywhere,
377 BreakWord,
380}
381impl_option!(
382 StyleOverflowWrap,
383 OptionStyleOverflowWrap,
384 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
385);
386impl PrintAsCssValue for StyleOverflowWrap {
387 fn print_as_css_value(&self) -> String {
388 String::from(match self {
389 StyleOverflowWrap::Normal => "normal",
390 StyleOverflowWrap::Anywhere => "anywhere",
391 StyleOverflowWrap::BreakWord => "break-word",
392 })
393 }
394}
395
396#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
403#[repr(C)]
404#[derive(Default)]
405pub enum StyleTextAlignLast {
406 #[default]
408 Auto,
409 Start,
411 End,
413 Left,
415 Right,
417 Center,
419 Justify,
421}
422impl_option!(
423 StyleTextAlignLast,
424 OptionStyleTextAlignLast,
425 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
426);
427impl PrintAsCssValue for StyleTextAlignLast {
428 fn print_as_css_value(&self) -> String {
429 String::from(match self {
430 StyleTextAlignLast::Auto => "auto",
431 StyleTextAlignLast::Start => "start",
432 StyleTextAlignLast::End => "end",
433 StyleTextAlignLast::Left => "left",
434 StyleTextAlignLast::Right => "right",
435 StyleTextAlignLast::Center => "center",
436 StyleTextAlignLast::Justify => "justify",
437 })
438 }
439}
440
441#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
446#[repr(C)]
447#[derive(Default)]
448pub enum StyleDirection {
449 #[default]
451 Ltr,
452 Rtl,
454}
455impl_option!(
456 StyleDirection,
457 OptionStyleDirection,
458 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
459);
460impl PrintAsCssValue for StyleDirection {
461 fn print_as_css_value(&self) -> String {
462 String::from(match self {
463 StyleDirection::Ltr => "ltr",
464 StyleDirection::Rtl => "rtl",
465 })
466 }
467}
468
469#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
474#[repr(C)]
475#[derive(Default)]
476pub enum StyleUserSelect {
477 #[default]
479 Auto,
480 Text,
482 None,
484 All,
486}
487impl_option!(
488 StyleUserSelect,
489 OptionStyleUserSelect,
490 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
491);
492impl PrintAsCssValue for StyleUserSelect {
493 fn print_as_css_value(&self) -> String {
494 String::from(match self {
495 StyleUserSelect::Auto => "auto",
496 StyleUserSelect::Text => "text",
497 StyleUserSelect::None => "none",
498 StyleUserSelect::All => "all",
499 })
500 }
501}
502
503#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
507#[repr(C)]
508#[derive(Default)]
509pub enum StyleTextDecoration {
510 #[default]
512 None,
513 Underline,
515 Overline,
517 LineThrough,
519}
520impl_option!(
521 StyleTextDecoration,
522 OptionStyleTextDecoration,
523 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
524);
525impl PrintAsCssValue for StyleTextDecoration {
526 fn print_as_css_value(&self) -> String {
527 String::from(match self {
528 StyleTextDecoration::None => "none",
529 StyleTextDecoration::Underline => "underline",
530 StyleTextDecoration::Overline => "overline",
531 StyleTextDecoration::LineThrough => "line-through",
532 })
533 }
534}
535
536#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
540#[repr(C, u8)]
541#[derive(Default)]
542pub enum StyleVerticalAlign {
543 #[default]
545 Baseline,
546 Top,
548 Middle,
550 Bottom,
552 Sub,
554 Superscript,
556 TextTop,
558 TextBottom,
560 Percentage(PercentageValue),
562 Length(PixelValue),
564}
565
566impl_option!(
567 StyleVerticalAlign,
568 OptionStyleVerticalAlign,
569 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
570);
571
572impl PrintAsCssValue for StyleVerticalAlign {
573 fn print_as_css_value(&self) -> String {
574 match self {
575 StyleVerticalAlign::Baseline => String::from("baseline"),
576 StyleVerticalAlign::Top => String::from("top"),
577 StyleVerticalAlign::Middle => String::from("middle"),
578 StyleVerticalAlign::Bottom => String::from("bottom"),
579 StyleVerticalAlign::Sub => String::from("sub"),
580 StyleVerticalAlign::Superscript => String::from("super"),
581 StyleVerticalAlign::TextTop => String::from("text-top"),
582 StyleVerticalAlign::TextBottom => String::from("text-bottom"),
583 StyleVerticalAlign::Percentage(p) => format!("{}%", p.normalized() * 100.0),
584 StyleVerticalAlign::Length(l) => l.print_as_css_value(),
585 }
586 }
587}
588
589impl crate::format_rust_code::FormatAsRustCode for StyleVerticalAlign {
590 fn format_as_rust_code(&self, indent: usize) -> String {
591 match self {
592 StyleVerticalAlign::Baseline => "StyleVerticalAlign::Baseline".to_string(),
593 StyleVerticalAlign::Top => "StyleVerticalAlign::Top".to_string(),
594 StyleVerticalAlign::Middle => "StyleVerticalAlign::Middle".to_string(),
595 StyleVerticalAlign::Bottom => "StyleVerticalAlign::Bottom".to_string(),
596 StyleVerticalAlign::Sub => "StyleVerticalAlign::Sub".to_string(),
597 StyleVerticalAlign::Superscript => "StyleVerticalAlign::Superscript".to_string(),
598 StyleVerticalAlign::TextTop => "StyleVerticalAlign::TextTop".to_string(),
599 StyleVerticalAlign::TextBottom => "StyleVerticalAlign::TextBottom".to_string(),
600 StyleVerticalAlign::Percentage(p) => format!("StyleVerticalAlign::Percentage(PercentageValue::new({}))", p.normalized() * 100.0),
601 StyleVerticalAlign::Length(l) => format!("StyleVerticalAlign::Length({})", l),
602 }
603 }
604}
605
606#[cfg(feature = "parser")]
609use crate::props::basic::{
610 color::{parse_css_color, CssColorParseError, CssColorParseErrorOwned},
611 DurationParseError,
612};
613
614#[cfg(feature = "parser")]
615#[derive(Clone, PartialEq)]
616pub enum StyleTextColorParseError<'a> {
617 ColorParseError(CssColorParseError<'a>),
618}
619#[cfg(feature = "parser")]
620impl_debug_as_display!(StyleTextColorParseError<'a>);
621#[cfg(feature = "parser")]
622impl_display! { StyleTextColorParseError<'a>, {
623 ColorParseError(e) => format!("Invalid color: {}", e),
624}}
625#[cfg(feature = "parser")]
626impl_from!(
627 CssColorParseError<'a>,
628 StyleTextColorParseError::ColorParseError
629);
630
631#[cfg(feature = "parser")]
632#[derive(Debug, Clone, PartialEq)]
633#[repr(C, u8)]
634pub enum StyleTextColorParseErrorOwned {
635 ColorParseError(CssColorParseErrorOwned),
636}
637
638#[cfg(feature = "parser")]
639impl<'a> StyleTextColorParseError<'a> {
640 pub fn to_contained(&self) -> StyleTextColorParseErrorOwned {
641 match self {
642 Self::ColorParseError(e) => {
643 StyleTextColorParseErrorOwned::ColorParseError(e.to_contained())
644 }
645 }
646 }
647}
648
649#[cfg(feature = "parser")]
650impl StyleTextColorParseErrorOwned {
651 pub fn to_shared<'a>(&'a self) -> StyleTextColorParseError<'a> {
652 match self {
653 Self::ColorParseError(e) => StyleTextColorParseError::ColorParseError(e.to_shared()),
654 }
655 }
656}
657
658#[cfg(feature = "parser")]
659pub fn parse_style_text_color(input: &str) -> Result<StyleTextColor, StyleTextColorParseError<'_>> {
660 parse_css_color(input)
661 .map(|inner| StyleTextColor { inner })
662 .map_err(StyleTextColorParseError::ColorParseError)
663}
664
665#[cfg(feature = "parser")]
666#[derive(Clone, PartialEq)]
667pub enum StyleTextAlignParseError<'a> {
668 InvalidValue(InvalidValueErr<'a>),
669}
670#[cfg(feature = "parser")]
671impl_debug_as_display!(StyleTextAlignParseError<'a>);
672#[cfg(feature = "parser")]
673impl_display! { StyleTextAlignParseError<'a>, {
674 InvalidValue(e) => format!("Invalid text-align value: \"{}\"", e.0),
675}}
676#[cfg(feature = "parser")]
677impl_from!(InvalidValueErr<'a>, StyleTextAlignParseError::InvalidValue);
678
679#[cfg(feature = "parser")]
680#[derive(Debug, Clone, PartialEq)]
681#[repr(C, u8)]
682pub enum StyleTextAlignParseErrorOwned {
683 InvalidValue(InvalidValueErrOwned),
684}
685
686#[cfg(feature = "parser")]
687impl<'a> StyleTextAlignParseError<'a> {
688 pub fn to_contained(&self) -> StyleTextAlignParseErrorOwned {
689 match self {
690 Self::InvalidValue(e) => StyleTextAlignParseErrorOwned::InvalidValue(e.to_contained()),
691 }
692 }
693}
694
695#[cfg(feature = "parser")]
696impl StyleTextAlignParseErrorOwned {
697 pub fn to_shared<'a>(&'a self) -> StyleTextAlignParseError<'a> {
698 match self {
699 Self::InvalidValue(e) => StyleTextAlignParseError::InvalidValue(e.to_shared()),
700 }
701 }
702}
703
704#[cfg(feature = "parser")]
705pub fn parse_style_text_align(input: &str) -> Result<StyleTextAlign, StyleTextAlignParseError<'_>> {
706 match input.trim() {
707 "left" => Ok(StyleTextAlign::Left),
708 "center" => Ok(StyleTextAlign::Center),
709 "right" => Ok(StyleTextAlign::Right),
710 "justify" => Ok(StyleTextAlign::Justify),
711 "start" => Ok(StyleTextAlign::Start),
712 "end" => Ok(StyleTextAlign::End),
713 other => Err(StyleTextAlignParseError::InvalidValue(InvalidValueErr(
714 other,
715 ))),
716 }
717}
718
719#[cfg(feature = "parser")]
720#[derive(Clone, PartialEq)]
721pub enum StyleLetterSpacingParseError<'a> {
722 PixelValue(CssPixelValueParseError<'a>),
723}
724#[cfg(feature = "parser")]
725impl_debug_as_display!(StyleLetterSpacingParseError<'a>);
726#[cfg(feature = "parser")]
727impl_display! { StyleLetterSpacingParseError<'a>, {
728 PixelValue(e) => format!("Invalid letter-spacing value: {}", e),
729}}
730#[cfg(feature = "parser")]
731impl_from!(
732 CssPixelValueParseError<'a>,
733 StyleLetterSpacingParseError::PixelValue
734);
735
736#[cfg(feature = "parser")]
737#[derive(Debug, Clone, PartialEq)]
738#[repr(C, u8)]
739pub enum StyleLetterSpacingParseErrorOwned {
740 PixelValue(CssPixelValueParseErrorOwned),
741}
742
743#[cfg(feature = "parser")]
744impl<'a> StyleLetterSpacingParseError<'a> {
745 pub fn to_contained(&self) -> StyleLetterSpacingParseErrorOwned {
746 match self {
747 Self::PixelValue(e) => StyleLetterSpacingParseErrorOwned::PixelValue(e.to_contained()),
748 }
749 }
750}
751
752#[cfg(feature = "parser")]
753impl StyleLetterSpacingParseErrorOwned {
754 pub fn to_shared<'a>(&'a self) -> StyleLetterSpacingParseError<'a> {
755 match self {
756 Self::PixelValue(e) => StyleLetterSpacingParseError::PixelValue(e.to_shared()),
757 }
758 }
759}
760
761#[cfg(feature = "parser")]
762pub fn parse_style_letter_spacing(
763 input: &str,
764) -> Result<StyleLetterSpacing, StyleLetterSpacingParseError<'_>> {
765 crate::props::basic::pixel::parse_pixel_value(input)
766 .map(|inner| StyleLetterSpacing { inner })
767 .map_err(StyleLetterSpacingParseError::PixelValue)
768}
769
770#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
774#[repr(C)]
775pub struct StyleTextIndent {
776 pub inner: PixelValue,
777 pub each_line: bool,
780 pub hanging: bool,
782}
783
784impl fmt::Debug for StyleTextIndent {
785 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
786 write!(f, "{}", self.print_as_css_value())
787 }
788}
789
790impl StyleTextIndent {
791 #[inline]
792 pub const fn zero() -> Self {
793 Self { inner: crate::props::basic::pixel::PixelValue::zero(), each_line: false, hanging: false }
794 }
795 #[inline]
796 pub const fn const_px(value: isize) -> Self {
797 Self { inner: crate::props::basic::pixel::PixelValue::const_px(value), each_line: false, hanging: false }
798 }
799 #[inline]
800 pub const fn const_em(value: isize) -> Self {
801 Self { inner: crate::props::basic::pixel::PixelValue::const_em(value), each_line: false, hanging: false }
802 }
803 #[inline]
804 pub const fn const_pt(value: isize) -> Self {
805 Self { inner: crate::props::basic::pixel::PixelValue::const_pt(value), each_line: false, hanging: false }
806 }
807 #[inline]
808 pub const fn const_percent(value: isize) -> Self {
809 Self { inner: crate::props::basic::pixel::PixelValue::const_percent(value), each_line: false, hanging: false }
810 }
811 #[inline]
812 pub const fn const_in(value: isize) -> Self {
813 Self { inner: crate::props::basic::pixel::PixelValue::const_in(value), each_line: false, hanging: false }
814 }
815 #[inline]
816 pub const fn const_cm(value: isize) -> Self {
817 Self { inner: crate::props::basic::pixel::PixelValue::const_cm(value), each_line: false, hanging: false }
818 }
819 #[inline]
820 pub const fn const_mm(value: isize) -> Self {
821 Self { inner: crate::props::basic::pixel::PixelValue::const_mm(value), each_line: false, hanging: false }
822 }
823 #[inline]
824 pub const fn const_from_metric(metric: crate::props::basic::length::SizeMetric, value: isize) -> Self {
825 Self { inner: crate::props::basic::pixel::PixelValue::const_from_metric(metric, value), each_line: false, hanging: false }
826 }
827 #[inline]
828 pub fn px(value: f32) -> Self {
829 Self { inner: crate::props::basic::pixel::PixelValue::px(value), each_line: false, hanging: false }
830 }
831 #[inline]
832 pub fn em(value: f32) -> Self {
833 Self { inner: crate::props::basic::pixel::PixelValue::em(value), each_line: false, hanging: false }
834 }
835 #[inline]
836 pub fn pt(value: f32) -> Self {
837 Self { inner: crate::props::basic::pixel::PixelValue::pt(value), each_line: false, hanging: false }
838 }
839 #[inline]
840 pub fn percent(value: f32) -> Self {
841 Self { inner: crate::props::basic::pixel::PixelValue::percent(value), each_line: false, hanging: false }
842 }
843 #[inline]
844 pub fn from_metric(metric: crate::props::basic::length::SizeMetric, value: f32) -> Self {
845 Self { inner: crate::props::basic::pixel::PixelValue::from_metric(metric, value), each_line: false, hanging: false }
846 }
847 #[inline]
848 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
849 StyleTextIndent { inner: self.inner.interpolate(&other.inner, t), each_line: self.each_line, hanging: self.hanging }
850 }
851}
852
853impl PrintAsCssValue for StyleTextIndent {
854 fn print_as_css_value(&self) -> String {
855 let mut s = self.inner.to_string();
856 if self.hanging {
857 s.push_str(" hanging");
858 }
859 if self.each_line {
860 s.push_str(" each-line");
861 }
862 s
863 }
864}
865
866impl crate::format_rust_code::FormatAsRustCode for StyleTextIndent {
867 fn format_as_rust_code(&self, _tabs: usize) -> String {
868 format!(
869 "StyleTextIndent {{ inner: {}, each_line: {}, hanging: {} }}",
870 self.inner.format_as_rust_code(0), self.each_line, self.hanging
871 )
872 }
873}
874
875#[cfg(feature = "parser")]
876#[derive(Clone, PartialEq)]
877pub enum StyleTextIndentParseError<'a> {
878 PixelValue(CssPixelValueParseError<'a>),
879}
880#[cfg(feature = "parser")]
881impl_debug_as_display!(StyleTextIndentParseError<'a>);
882#[cfg(feature = "parser")]
883impl_display! { StyleTextIndentParseError<'a>, {
884 PixelValue(e) => format!("Invalid text-indent value: {}", e),
885}}
886#[cfg(feature = "parser")]
887impl_from!(
888 CssPixelValueParseError<'a>,
889 StyleTextIndentParseError::PixelValue
890);
891
892#[cfg(feature = "parser")]
893#[derive(Debug, Clone, PartialEq)]
894#[repr(C, u8)]
895pub enum StyleTextIndentParseErrorOwned {
896 PixelValue(CssPixelValueParseErrorOwned),
897}
898
899#[cfg(feature = "parser")]
900impl<'a> StyleTextIndentParseError<'a> {
901 pub fn to_contained(&self) -> StyleTextIndentParseErrorOwned {
902 match self {
903 Self::PixelValue(e) => StyleTextIndentParseErrorOwned::PixelValue(e.to_contained()),
904 }
905 }
906}
907
908#[cfg(feature = "parser")]
909impl StyleTextIndentParseErrorOwned {
910 pub fn to_shared<'a>(&'a self) -> StyleTextIndentParseError<'a> {
911 match self {
912 Self::PixelValue(e) => StyleTextIndentParseError::PixelValue(e.to_shared()),
913 }
914 }
915}
916
917#[cfg(feature = "parser")]
918pub fn parse_style_text_indent(input: &str) -> Result<StyleTextIndent, StyleTextIndentParseError<'_>> {
919 let mut each_line = false;
920 let mut hanging = false;
921 let mut pixel_part: Option<&str> = None;
922
923 for token in input.split_whitespace() {
924 match token {
925 "each-line" => each_line = true,
926 "hanging" => hanging = true,
927 _ => {
928 pixel_part = Some(token);
929 }
930 }
931 }
932
933 let pixel_str = pixel_part.unwrap_or("0px");
934
935 crate::props::basic::pixel::parse_pixel_value(pixel_str)
936 .map(|inner| StyleTextIndent { inner, each_line, hanging })
937 .map_err(StyleTextIndentParseError::PixelValue)
938}
939
940#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
942#[repr(C)]
943pub struct StyleInitialLetter {
944 pub size: u32,
945 pub sink: crate::corety::OptionU32,
946}
947
948impl FormatAsRustCode for StyleInitialLetter {
949 fn format_as_rust_code(&self, _tabs: usize) -> String {
950 format!("{:?}", self)
951 }
952}
953
954impl PrintAsCssValue for StyleInitialLetter {
955 fn print_as_css_value(&self) -> String {
956 if let crate::corety::OptionU32::Some(sink) = self.sink {
957 format!("{} {}", self.size, sink)
958 } else {
959 format!("{}", self.size)
960 }
961 }
962}
963
964#[cfg(feature = "parser")]
965#[derive(Clone, PartialEq)]
966pub enum StyleInitialLetterParseError<'a> {
967 InvalidFormat(&'a str),
968 InvalidSize(&'a str),
969 InvalidSink(&'a str),
970}
971#[cfg(feature = "parser")]
972impl_debug_as_display!(StyleInitialLetterParseError<'a>);
973#[cfg(feature = "parser")]
974impl_display! { StyleInitialLetterParseError<'a>, {
975 InvalidFormat(e) => format!("Invalid initial-letter format: {}", e),
976 InvalidSize(e) => format!("Invalid initial-letter size: {}", e),
977 InvalidSink(e) => format!("Invalid initial-letter sink: {}", e),
978}}
979
980#[cfg(feature = "parser")]
981#[derive(Debug, Clone, PartialEq)]
982#[repr(C, u8)]
983pub enum StyleInitialLetterParseErrorOwned {
984 InvalidFormat(AzString),
985 InvalidSize(AzString),
986 InvalidSink(AzString),
987}
988
989#[cfg(feature = "parser")]
990impl<'a> StyleInitialLetterParseError<'a> {
991 pub fn to_contained(&self) -> StyleInitialLetterParseErrorOwned {
992 match self {
993 Self::InvalidFormat(s) => {
994 StyleInitialLetterParseErrorOwned::InvalidFormat(s.to_string().into())
995 }
996 Self::InvalidSize(s) => StyleInitialLetterParseErrorOwned::InvalidSize(s.to_string().into()),
997 Self::InvalidSink(s) => StyleInitialLetterParseErrorOwned::InvalidSink(s.to_string().into()),
998 }
999 }
1000}
1001
1002#[cfg(feature = "parser")]
1003impl StyleInitialLetterParseErrorOwned {
1004 pub fn to_shared<'a>(&'a self) -> StyleInitialLetterParseError<'a> {
1005 match self {
1006 Self::InvalidFormat(s) => StyleInitialLetterParseError::InvalidFormat(s.as_str()),
1007 Self::InvalidSize(s) => StyleInitialLetterParseError::InvalidSize(s.as_str()),
1008 Self::InvalidSink(s) => StyleInitialLetterParseError::InvalidSink(s.as_str()),
1009 }
1010 }
1011}
1012
1013#[cfg(feature = "parser")]
1014impl From<StyleInitialLetterParseError<'_>> for StyleInitialLetterParseErrorOwned {
1015 fn from(e: StyleInitialLetterParseError) -> Self {
1016 match e {
1017 StyleInitialLetterParseError::InvalidFormat(s) => {
1018 StyleInitialLetterParseErrorOwned::InvalidFormat(s.to_string().into())
1019 }
1020 StyleInitialLetterParseError::InvalidSize(s) => {
1021 StyleInitialLetterParseErrorOwned::InvalidSize(s.to_string().into())
1022 }
1023 StyleInitialLetterParseError::InvalidSink(s) => {
1024 StyleInitialLetterParseErrorOwned::InvalidSink(s.to_string().into())
1025 }
1026 }
1027 }
1028}
1029
1030#[cfg(feature = "parser")]
1031impl_display! { StyleInitialLetterParseErrorOwned, {
1032 InvalidFormat(e) => format!("Invalid initial-letter format: {}", e),
1033 InvalidSize(e) => format!("Invalid initial-letter size: {}", e),
1034 InvalidSink(e) => format!("Invalid initial-letter sink: {}", e),
1035}}
1036
1037#[cfg(feature = "parser")]
1038pub fn parse_style_initial_letter<'a>(
1039 input: &'a str,
1040) -> Result<StyleInitialLetter, StyleInitialLetterParseError<'a>> {
1041 let input = input.trim();
1042 let parts: Vec<&str> = input.split_whitespace().collect();
1043
1044 if parts.is_empty() {
1045 return Err(StyleInitialLetterParseError::InvalidFormat(input));
1046 }
1047
1048 let size = parts[0]
1050 .parse::<u32>()
1051 .map_err(|_| StyleInitialLetterParseError::InvalidSize(parts[0]))?;
1052
1053 if size == 0 {
1054 return Err(StyleInitialLetterParseError::InvalidSize(parts[0]));
1055 }
1056
1057 let sink = if parts.len() > 1 {
1059 crate::corety::OptionU32::Some(
1060 parts[1]
1061 .parse::<u32>()
1062 .map_err(|_| StyleInitialLetterParseError::InvalidSink(parts[1]))?,
1063 )
1064 } else {
1065 crate::corety::OptionU32::None
1066 };
1067
1068 Ok(StyleInitialLetter { size, sink })
1069}
1070
1071#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1073#[repr(C)]
1074pub struct StyleLineClamp {
1075 pub max_lines: usize,
1076}
1077
1078impl FormatAsRustCode for StyleLineClamp {
1079 fn format_as_rust_code(&self, _tabs: usize) -> String {
1080 format!("{:?}", self)
1081 }
1082}
1083
1084impl PrintAsCssValue for StyleLineClamp {
1085 fn print_as_css_value(&self) -> String {
1086 format!("{}", self.max_lines)
1087 }
1088}
1089
1090#[cfg(feature = "parser")]
1091#[derive(Clone, PartialEq)]
1092pub enum StyleLineClampParseError<'a> {
1093 InvalidValue(&'a str),
1094 ZeroValue,
1095}
1096#[cfg(feature = "parser")]
1097impl_debug_as_display!(StyleLineClampParseError<'a>);
1098#[cfg(feature = "parser")]
1099impl_display! { StyleLineClampParseError<'a>, {
1100 InvalidValue(e) => format!("Invalid line-clamp value: {}", e),
1101 ZeroValue => format!("line-clamp cannot be zero"),
1102}}
1103
1104#[cfg(feature = "parser")]
1105#[derive(Debug, Clone, PartialEq)]
1106#[repr(C, u8)]
1107pub enum StyleLineClampParseErrorOwned {
1108 InvalidValue(AzString),
1109 ZeroValue,
1110}
1111
1112#[cfg(feature = "parser")]
1113impl<'a> StyleLineClampParseError<'a> {
1114 pub fn to_contained(&self) -> StyleLineClampParseErrorOwned {
1115 match self {
1116 Self::InvalidValue(s) => StyleLineClampParseErrorOwned::InvalidValue(s.to_string().into()),
1117 Self::ZeroValue => StyleLineClampParseErrorOwned::ZeroValue,
1118 }
1119 }
1120}
1121
1122#[cfg(feature = "parser")]
1123impl StyleLineClampParseErrorOwned {
1124 pub fn to_shared<'a>(&'a self) -> StyleLineClampParseError<'a> {
1125 match self {
1126 Self::InvalidValue(s) => StyleLineClampParseError::InvalidValue(s.as_str()),
1127 Self::ZeroValue => StyleLineClampParseError::ZeroValue,
1128 }
1129 }
1130}
1131
1132#[cfg(feature = "parser")]
1133impl From<StyleLineClampParseError<'_>> for StyleLineClampParseErrorOwned {
1134 fn from(e: StyleLineClampParseError) -> Self {
1135 e.to_contained()
1136 }
1137}
1138
1139#[cfg(feature = "parser")]
1140impl_display! { StyleLineClampParseErrorOwned, {
1141 InvalidValue(e) => format!("Invalid line-clamp value: {}", e),
1142 ZeroValue => format!("line-clamp cannot be zero"),
1143}}
1144
1145#[cfg(feature = "parser")]
1146pub fn parse_style_line_clamp<'a>(
1147 input: &'a str,
1148) -> Result<StyleLineClamp, StyleLineClampParseError<'a>> {
1149 let input = input.trim();
1150
1151 let max_lines = input
1152 .parse::<usize>()
1153 .map_err(|_| StyleLineClampParseError::InvalidValue(input))?;
1154
1155 if max_lines == 0 {
1156 return Err(StyleLineClampParseError::ZeroValue);
1157 }
1158
1159 Ok(StyleLineClamp { max_lines })
1160}
1161
1162#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1166#[repr(C)]
1167#[derive(Default)]
1168pub struct StyleHangingPunctuation {
1169 pub first: bool,
1170 pub force_end: bool,
1171 pub allow_end: bool,
1172 pub last: bool,
1173}
1174
1175impl StyleHangingPunctuation {
1176 pub fn is_enabled(&self) -> bool {
1177 self.first || self.force_end || self.allow_end || self.last
1178 }
1179}
1180
1181impl FormatAsRustCode for StyleHangingPunctuation {
1182 fn format_as_rust_code(&self, _tabs: usize) -> String {
1183 format!("{:?}", self)
1184 }
1185}
1186
1187impl PrintAsCssValue for StyleHangingPunctuation {
1188 fn print_as_css_value(&self) -> String {
1189 if !self.is_enabled() {
1190 return "none".to_string();
1191 }
1192 let mut parts = alloc::vec::Vec::new();
1193 if self.first { parts.push("first"); }
1194 if self.force_end { parts.push("force-end"); }
1195 if self.allow_end { parts.push("allow-end"); }
1196 if self.last { parts.push("last"); }
1197 parts.join(" ")
1198 }
1199}
1200
1201#[cfg(feature = "parser")]
1202#[derive(Clone, PartialEq)]
1203pub enum StyleHangingPunctuationParseError<'a> {
1204 InvalidValue(&'a str),
1205}
1206#[cfg(feature = "parser")]
1207impl_debug_as_display!(StyleHangingPunctuationParseError<'a>);
1208#[cfg(feature = "parser")]
1209impl_display! { StyleHangingPunctuationParseError<'a>, {
1210 InvalidValue(e) => format!("Invalid hanging-punctuation value: {}", e),
1211}}
1212
1213#[cfg(feature = "parser")]
1214#[derive(Debug, Clone, PartialEq)]
1215#[repr(C, u8)]
1216pub enum StyleHangingPunctuationParseErrorOwned {
1217 InvalidValue(AzString),
1218}
1219
1220#[cfg(feature = "parser")]
1221impl<'a> StyleHangingPunctuationParseError<'a> {
1222 pub fn to_contained(&self) -> StyleHangingPunctuationParseErrorOwned {
1223 match self {
1224 Self::InvalidValue(s) => {
1225 StyleHangingPunctuationParseErrorOwned::InvalidValue(s.to_string().into())
1226 }
1227 }
1228 }
1229}
1230
1231#[cfg(feature = "parser")]
1232impl StyleHangingPunctuationParseErrorOwned {
1233 pub fn to_shared<'a>(&'a self) -> StyleHangingPunctuationParseError<'a> {
1234 match self {
1235 Self::InvalidValue(s) => StyleHangingPunctuationParseError::InvalidValue(s.as_str()),
1236 }
1237 }
1238}
1239
1240#[cfg(feature = "parser")]
1241impl From<StyleHangingPunctuationParseError<'_>> for StyleHangingPunctuationParseErrorOwned {
1242 fn from(e: StyleHangingPunctuationParseError) -> Self {
1243 e.to_contained()
1244 }
1245}
1246
1247#[cfg(feature = "parser")]
1248impl_display! { StyleHangingPunctuationParseErrorOwned, {
1249 InvalidValue(e) => format!("Invalid hanging-punctuation value: {}", e),
1250}}
1251
1252#[cfg(feature = "parser")]
1253pub fn parse_style_hanging_punctuation<'a>(
1254 input: &'a str,
1255) -> Result<StyleHangingPunctuation, StyleHangingPunctuationParseError<'a>> {
1256 let input = input.trim();
1257
1258 if input.eq_ignore_ascii_case("none") {
1259 return Ok(StyleHangingPunctuation::default());
1260 }
1261
1262 let mut first = false;
1263 let mut force_end = false;
1264 let mut allow_end = false;
1265 let mut last = false;
1266
1267 for token in input.split_whitespace() {
1268 match token.to_lowercase().as_str() {
1269 "first" => first = true,
1270 "force-end" => force_end = true,
1271 "allow-end" => allow_end = true,
1272 "last" => last = true,
1273 _ => return Err(StyleHangingPunctuationParseError::InvalidValue(input)),
1274 }
1275 }
1276
1277 if force_end && allow_end {
1278 return Err(StyleHangingPunctuationParseError::InvalidValue(input));
1279 }
1280
1281 Ok(StyleHangingPunctuation { first, force_end, allow_end, last })
1282}
1283
1284#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1286#[repr(C, u8)]
1287#[derive(Default)]
1288pub enum StyleTextCombineUpright {
1289 #[default]
1290 None,
1291 All,
1292 Digits(u8),
1293}
1294
1295
1296impl FormatAsRustCode for StyleTextCombineUpright {
1297 fn format_as_rust_code(&self, _tabs: usize) -> String {
1298 format!("{:?}", self)
1299 }
1300}
1301
1302impl PrintAsCssValue for StyleTextCombineUpright {
1303 fn print_as_css_value(&self) -> String {
1304 match self {
1305 Self::None => "none".to_string(),
1306 Self::All => "all".to_string(),
1307 Self::Digits(n) => format!("digits {}", n),
1308 }
1309 }
1310}
1311
1312#[cfg(feature = "parser")]
1313#[derive(Clone, PartialEq)]
1314pub enum StyleTextCombineUprightParseError<'a> {
1315 InvalidValue(&'a str),
1316 InvalidDigits(&'a str),
1317}
1318#[cfg(feature = "parser")]
1319impl_debug_as_display!(StyleTextCombineUprightParseError<'a>);
1320#[cfg(feature = "parser")]
1321impl_display! { StyleTextCombineUprightParseError<'a>, {
1322 InvalidValue(e) => format!("Invalid text-combine-upright value: {}", e),
1323 InvalidDigits(e) => format!("Invalid text-combine-upright digits: {}", e),
1324}}
1325
1326#[cfg(feature = "parser")]
1327#[derive(Debug, Clone, PartialEq)]
1328#[repr(C, u8)]
1329pub enum StyleTextCombineUprightParseErrorOwned {
1330 InvalidValue(AzString),
1331 InvalidDigits(AzString),
1332}
1333
1334#[cfg(feature = "parser")]
1335impl<'a> StyleTextCombineUprightParseError<'a> {
1336 pub fn to_contained(&self) -> StyleTextCombineUprightParseErrorOwned {
1337 match self {
1338 Self::InvalidValue(s) => {
1339 StyleTextCombineUprightParseErrorOwned::InvalidValue(s.to_string().into())
1340 }
1341 Self::InvalidDigits(s) => {
1342 StyleTextCombineUprightParseErrorOwned::InvalidDigits(s.to_string().into())
1343 }
1344 }
1345 }
1346}
1347
1348#[cfg(feature = "parser")]
1349impl StyleTextCombineUprightParseErrorOwned {
1350 pub fn to_shared<'a>(&'a self) -> StyleTextCombineUprightParseError<'a> {
1351 match self {
1352 Self::InvalidValue(s) => StyleTextCombineUprightParseError::InvalidValue(s.as_str()),
1353 Self::InvalidDigits(s) => StyleTextCombineUprightParseError::InvalidDigits(s.as_str()),
1354 }
1355 }
1356}
1357
1358#[cfg(feature = "parser")]
1359impl From<StyleTextCombineUprightParseError<'_>> for StyleTextCombineUprightParseErrorOwned {
1360 fn from(e: StyleTextCombineUprightParseError) -> Self {
1361 e.to_contained()
1362 }
1363}
1364
1365#[cfg(feature = "parser")]
1366impl_display! { StyleTextCombineUprightParseErrorOwned, {
1367 InvalidValue(e) => format!("Invalid text-combine-upright value: {}", e),
1368 InvalidDigits(e) => format!("Invalid text-combine-upright digits: {}", e),
1369}}
1370
1371#[cfg(feature = "parser")]
1372pub fn parse_style_text_combine_upright<'a>(
1373 input: &'a str,
1374) -> Result<StyleTextCombineUpright, StyleTextCombineUprightParseError<'a>> {
1375 let trimmed = input.trim();
1376
1377 if trimmed.eq_ignore_ascii_case("none") {
1378 Ok(StyleTextCombineUpright::None)
1379 } else if trimmed.eq_ignore_ascii_case("all") {
1380 Ok(StyleTextCombineUpright::All)
1381 } else if trimmed.starts_with("digits") {
1382 let parts: Vec<&str> = trimmed.split_whitespace().collect();
1383 if parts.len() == 2 {
1384 let n = parts[1]
1385 .parse::<u8>()
1386 .map_err(|_| StyleTextCombineUprightParseError::InvalidDigits(input))?;
1387 if (2..=4).contains(&n) {
1388 Ok(StyleTextCombineUpright::Digits(n))
1389 } else {
1390 Err(StyleTextCombineUprightParseError::InvalidDigits(input))
1391 }
1392 } else {
1393 Ok(StyleTextCombineUpright::Digits(2))
1395 }
1396 } else {
1397 Err(StyleTextCombineUprightParseError::InvalidValue(input))
1398 }
1399}
1400
1401#[cfg(feature = "parser")]
1402#[derive(Clone, PartialEq)]
1403pub enum StyleWordSpacingParseError<'a> {
1404 PixelValue(CssPixelValueParseError<'a>),
1405}
1406#[cfg(feature = "parser")]
1407impl_debug_as_display!(StyleWordSpacingParseError<'a>);
1408#[cfg(feature = "parser")]
1409impl_display! { StyleWordSpacingParseError<'a>, {
1410 PixelValue(e) => format!("Invalid word-spacing value: {}", e),
1411}}
1412#[cfg(feature = "parser")]
1413impl_from!(
1414 CssPixelValueParseError<'a>,
1415 StyleWordSpacingParseError::PixelValue
1416);
1417
1418#[cfg(feature = "parser")]
1419#[derive(Debug, Clone, PartialEq)]
1420#[repr(C, u8)]
1421pub enum StyleWordSpacingParseErrorOwned {
1422 PixelValue(CssPixelValueParseErrorOwned),
1423}
1424
1425#[cfg(feature = "parser")]
1426impl<'a> StyleWordSpacingParseError<'a> {
1427 pub fn to_contained(&self) -> StyleWordSpacingParseErrorOwned {
1428 match self {
1429 Self::PixelValue(e) => StyleWordSpacingParseErrorOwned::PixelValue(e.to_contained()),
1430 }
1431 }
1432}
1433
1434#[cfg(feature = "parser")]
1435impl StyleWordSpacingParseErrorOwned {
1436 pub fn to_shared<'a>(&'a self) -> StyleWordSpacingParseError<'a> {
1437 match self {
1438 Self::PixelValue(e) => StyleWordSpacingParseError::PixelValue(e.to_shared()),
1439 }
1440 }
1441}
1442
1443#[cfg(feature = "parser")]
1444pub fn parse_style_word_spacing(
1445 input: &str,
1446) -> Result<StyleWordSpacing, StyleWordSpacingParseError<'_>> {
1447 crate::props::basic::pixel::parse_pixel_value(input)
1448 .map(|inner| StyleWordSpacing { inner })
1449 .map_err(StyleWordSpacingParseError::PixelValue)
1450}
1451
1452#[cfg(feature = "parser")]
1453#[derive(Clone, PartialEq)]
1454#[repr(C, u8)]
1455pub enum StyleLineHeightParseError {
1456 Percentage(PercentageParseError),
1457}
1458#[cfg(feature = "parser")]
1459impl_debug_as_display!(StyleLineHeightParseError);
1460#[cfg(feature = "parser")]
1461impl_display! { StyleLineHeightParseError, {
1462 Percentage(e) => format!("Invalid line-height value: {}", e),
1463}}
1464#[cfg(feature = "parser")]
1465impl_from!(PercentageParseError, StyleLineHeightParseError::Percentage);
1466
1467#[cfg(feature = "parser")]
1468#[derive(Debug, Clone, PartialEq)]
1469pub enum StyleLineHeightParseErrorOwned {
1470 Percentage(PercentageParseErrorOwned),
1471}
1472
1473#[cfg(feature = "parser")]
1474impl StyleLineHeightParseError {
1475 pub fn to_contained(&self) -> StyleLineHeightParseErrorOwned {
1476 match self {
1477 Self::Percentage(e) => StyleLineHeightParseErrorOwned::Percentage(e.to_contained()),
1478 }
1479 }
1480}
1481
1482#[cfg(feature = "parser")]
1483impl StyleLineHeightParseErrorOwned {
1484 pub fn to_shared(&self) -> StyleLineHeightParseError {
1485 match self {
1486 Self::Percentage(e) => StyleLineHeightParseError::Percentage(e.to_shared()),
1487 }
1488 }
1489}
1490
1491#[cfg(feature = "parser")]
1492pub fn parse_style_line_height(input: &str) -> Result<StyleLineHeight, StyleLineHeightParseError> {
1493 if let Ok(inner) = crate::props::basic::length::parse_percentage_value(input) {
1495 return Ok(StyleLineHeight { inner });
1496 }
1497 if let Ok(px) = crate::props::basic::pixel::parse_pixel_value(input) {
1501 if px.metric == crate::props::basic::length::SizeMetric::Px {
1502 let px_val = px.number.get();
1503 return Ok(StyleLineHeight {
1504 inner: crate::props::basic::length::PercentageValue::new(-px_val * 100.0),
1505 });
1506 }
1507 }
1508 Err(StyleLineHeightParseError::Percentage(
1509 crate::props::basic::length::PercentageParseError::InvalidUnit("".to_string().into()),
1510 ))
1511}
1512
1513#[cfg(feature = "parser")]
1514#[derive(Clone, PartialEq)]
1515pub enum StyleTabSizeParseError<'a> {
1516 PixelValue(CssPixelValueParseError<'a>),
1517}
1518#[cfg(feature = "parser")]
1519impl_debug_as_display!(StyleTabSizeParseError<'a>);
1520#[cfg(feature = "parser")]
1521impl_display! { StyleTabSizeParseError<'a>, {
1522 PixelValue(e) => format!("Invalid tab-size value: {}", e),
1523}}
1524#[cfg(feature = "parser")]
1525impl_from!(
1526 CssPixelValueParseError<'a>,
1527 StyleTabSizeParseError::PixelValue
1528);
1529
1530#[cfg(feature = "parser")]
1531#[derive(Debug, Clone, PartialEq)]
1532#[repr(C, u8)]
1533pub enum StyleTabSizeParseErrorOwned {
1534 PixelValue(CssPixelValueParseErrorOwned),
1535}
1536
1537#[cfg(feature = "parser")]
1538impl<'a> StyleTabSizeParseError<'a> {
1539 pub fn to_contained(&self) -> StyleTabSizeParseErrorOwned {
1540 match self {
1541 Self::PixelValue(e) => StyleTabSizeParseErrorOwned::PixelValue(e.to_contained()),
1542 }
1543 }
1544}
1545
1546#[cfg(feature = "parser")]
1547impl StyleTabSizeParseErrorOwned {
1548 pub fn to_shared<'a>(&'a self) -> StyleTabSizeParseError<'a> {
1549 match self {
1550 Self::PixelValue(e) => StyleTabSizeParseError::PixelValue(e.to_shared()),
1551 }
1552 }
1553}
1554
1555#[cfg(feature = "parser")]
1556pub fn parse_style_tab_size(input: &str) -> Result<StyleTabSize, StyleTabSizeParseError<'_>> {
1557 if let Ok(number) = input.trim().parse::<f32>() {
1558 Ok(StyleTabSize {
1559 inner: PixelValue::em(number),
1560 })
1561 } else {
1562 crate::props::basic::pixel::parse_pixel_value(input)
1563 .map(|v| StyleTabSize { inner: v })
1564 .map_err(StyleTabSizeParseError::PixelValue)
1565 }
1566}
1567
1568#[cfg(feature = "parser")]
1569#[derive(Clone, PartialEq)]
1570pub enum StyleWhiteSpaceParseError<'a> {
1571 InvalidValue(InvalidValueErr<'a>),
1572}
1573#[cfg(feature = "parser")]
1574impl_debug_as_display!(StyleWhiteSpaceParseError<'a>);
1575#[cfg(feature = "parser")]
1576impl_display! { StyleWhiteSpaceParseError<'a>, {
1577 InvalidValue(e) => format!("Invalid white-space value: \"{}\"", e.0),
1578}}
1579#[cfg(feature = "parser")]
1580impl_from!(InvalidValueErr<'a>, StyleWhiteSpaceParseError::InvalidValue);
1581
1582#[cfg(feature = "parser")]
1583#[derive(Debug, Clone, PartialEq)]
1584#[repr(C, u8)]
1585pub enum StyleWhiteSpaceParseErrorOwned {
1586 InvalidValue(InvalidValueErrOwned),
1587}
1588
1589#[cfg(feature = "parser")]
1590impl<'a> StyleWhiteSpaceParseError<'a> {
1591 pub fn to_contained(&self) -> StyleWhiteSpaceParseErrorOwned {
1592 match self {
1593 Self::InvalidValue(e) => StyleWhiteSpaceParseErrorOwned::InvalidValue(e.to_contained()),
1594 }
1595 }
1596}
1597
1598#[cfg(feature = "parser")]
1599impl StyleWhiteSpaceParseErrorOwned {
1600 pub fn to_shared<'a>(&'a self) -> StyleWhiteSpaceParseError<'a> {
1601 match self {
1602 Self::InvalidValue(e) => StyleWhiteSpaceParseError::InvalidValue(e.to_shared()),
1603 }
1604 }
1605}
1606
1607#[cfg(feature = "parser")]
1608pub fn parse_style_white_space(input: &str) -> Result<StyleWhiteSpace, StyleWhiteSpaceParseError<'_>> {
1609 match input.trim() {
1610 "normal" => Ok(StyleWhiteSpace::Normal),
1611 "pre" => Ok(StyleWhiteSpace::Pre),
1612 "nowrap" | "no-wrap" => Ok(StyleWhiteSpace::Nowrap),
1613 "pre-wrap" => Ok(StyleWhiteSpace::PreWrap),
1614 "pre-line" => Ok(StyleWhiteSpace::PreLine),
1615 "break-spaces" => Ok(StyleWhiteSpace::BreakSpaces),
1616 other => Err(StyleWhiteSpaceParseError::InvalidValue(InvalidValueErr(
1617 other,
1618 ))),
1619 }
1620}
1621
1622#[cfg(feature = "parser")]
1623#[derive(Clone, PartialEq)]
1624pub enum StyleHyphensParseError<'a> {
1625 InvalidValue(InvalidValueErr<'a>),
1626}
1627#[cfg(feature = "parser")]
1628impl_debug_as_display!(StyleHyphensParseError<'a>);
1629#[cfg(feature = "parser")]
1630impl_display! { StyleHyphensParseError<'a>, {
1631 InvalidValue(e) => format!("Invalid hyphens value: \"{}\"", e.0),
1632}}
1633#[cfg(feature = "parser")]
1634impl_from!(InvalidValueErr<'a>, StyleHyphensParseError::InvalidValue);
1635
1636#[cfg(feature = "parser")]
1637#[derive(Debug, Clone, PartialEq)]
1638#[repr(C, u8)]
1639pub enum StyleHyphensParseErrorOwned {
1640 InvalidValue(InvalidValueErrOwned),
1641}
1642
1643#[cfg(feature = "parser")]
1644impl<'a> StyleHyphensParseError<'a> {
1645 pub fn to_contained(&self) -> StyleHyphensParseErrorOwned {
1646 match self {
1647 Self::InvalidValue(e) => StyleHyphensParseErrorOwned::InvalidValue(e.to_contained()),
1648 }
1649 }
1650}
1651
1652#[cfg(feature = "parser")]
1653impl StyleHyphensParseErrorOwned {
1654 pub fn to_shared<'a>(&'a self) -> StyleHyphensParseError<'a> {
1655 match self {
1656 Self::InvalidValue(e) => StyleHyphensParseError::InvalidValue(e.to_shared()),
1657 }
1658 }
1659}
1660
1661#[cfg(feature = "parser")]
1662pub fn parse_style_hyphens(input: &str) -> Result<StyleHyphens, StyleHyphensParseError<'_>> {
1663 match input.trim() {
1664 "none" => Ok(StyleHyphens::None),
1665 "manual" => Ok(StyleHyphens::Manual),
1666 "auto" => Ok(StyleHyphens::Auto),
1667 other => Err(StyleHyphensParseError::InvalidValue(InvalidValueErr(other))),
1668 }
1669}
1670
1671#[cfg(feature = "parser")]
1674#[derive(Clone, PartialEq)]
1675pub enum StyleLineBreakParseError<'a> {
1676 InvalidValue(InvalidValueErr<'a>),
1677}
1678#[cfg(feature = "parser")]
1679impl_debug_as_display!(StyleLineBreakParseError<'a>);
1680#[cfg(feature = "parser")]
1681impl_display! { StyleLineBreakParseError<'a>, {
1682 InvalidValue(e) => format!("Invalid line-break value: \"{}\"", e.0),
1683}}
1684#[cfg(feature = "parser")]
1685impl_from!(InvalidValueErr<'a>, StyleLineBreakParseError::InvalidValue);
1686
1687#[cfg(feature = "parser")]
1688#[derive(Debug, Clone, PartialEq)]
1689#[repr(C, u8)]
1690pub enum StyleLineBreakParseErrorOwned {
1691 InvalidValue(InvalidValueErrOwned),
1692}
1693
1694#[cfg(feature = "parser")]
1695impl<'a> StyleLineBreakParseError<'a> {
1696 pub fn to_contained(&self) -> StyleLineBreakParseErrorOwned {
1697 match self {
1698 Self::InvalidValue(e) => StyleLineBreakParseErrorOwned::InvalidValue(e.to_contained()),
1699 }
1700 }
1701}
1702
1703#[cfg(feature = "parser")]
1704impl StyleLineBreakParseErrorOwned {
1705 pub fn to_shared<'a>(&'a self) -> StyleLineBreakParseError<'a> {
1706 match self {
1707 Self::InvalidValue(e) => StyleLineBreakParseError::InvalidValue(e.to_shared()),
1708 }
1709 }
1710}
1711
1712#[cfg(feature = "parser")]
1713pub fn parse_style_line_break(input: &str) -> Result<StyleLineBreak, StyleLineBreakParseError<'_>> {
1714 match input.trim() {
1715 "auto" => Ok(StyleLineBreak::Auto),
1716 "loose" => Ok(StyleLineBreak::Loose),
1717 "normal" => Ok(StyleLineBreak::Normal),
1718 "strict" => Ok(StyleLineBreak::Strict),
1719 "anywhere" => Ok(StyleLineBreak::Anywhere),
1720 other => Err(StyleLineBreakParseError::InvalidValue(InvalidValueErr(other))),
1721 }
1722}
1723
1724#[cfg(feature = "parser")]
1727#[derive(Clone, PartialEq)]
1728pub enum StyleWordBreakParseError<'a> {
1729 InvalidValue(InvalidValueErr<'a>),
1730}
1731#[cfg(feature = "parser")]
1732impl_debug_as_display!(StyleWordBreakParseError<'a>);
1733#[cfg(feature = "parser")]
1734impl_display! { StyleWordBreakParseError<'a>, {
1735 InvalidValue(e) => format!("Invalid word-break value: \"{}\"", e.0),
1736}}
1737#[cfg(feature = "parser")]
1738impl_from!(InvalidValueErr<'a>, StyleWordBreakParseError::InvalidValue);
1739
1740#[cfg(feature = "parser")]
1741#[derive(Debug, Clone, PartialEq)]
1742#[repr(C, u8)]
1743pub enum StyleWordBreakParseErrorOwned {
1744 InvalidValue(InvalidValueErrOwned),
1745}
1746
1747#[cfg(feature = "parser")]
1748impl<'a> StyleWordBreakParseError<'a> {
1749 pub fn to_contained(&self) -> StyleWordBreakParseErrorOwned {
1750 match self {
1751 Self::InvalidValue(e) => StyleWordBreakParseErrorOwned::InvalidValue(e.to_contained()),
1752 }
1753 }
1754}
1755
1756#[cfg(feature = "parser")]
1757impl StyleWordBreakParseErrorOwned {
1758 pub fn to_shared<'a>(&'a self) -> StyleWordBreakParseError<'a> {
1759 match self {
1760 Self::InvalidValue(e) => StyleWordBreakParseError::InvalidValue(e.to_shared()),
1761 }
1762 }
1763}
1764
1765#[cfg(feature = "parser")]
1766pub fn parse_style_word_break(input: &str) -> Result<StyleWordBreak, StyleWordBreakParseError<'_>> {
1767 match input.trim() {
1768 "normal" => Ok(StyleWordBreak::Normal),
1769 "break-all" => Ok(StyleWordBreak::BreakAll),
1770 "keep-all" => Ok(StyleWordBreak::KeepAll),
1771 "break-word" => Ok(StyleWordBreak::BreakWord),
1772 other => Err(StyleWordBreakParseError::InvalidValue(InvalidValueErr(other))),
1773 }
1774}
1775
1776#[cfg(feature = "parser")]
1779#[derive(Clone, PartialEq)]
1780pub enum StyleOverflowWrapParseError<'a> {
1781 InvalidValue(InvalidValueErr<'a>),
1782}
1783#[cfg(feature = "parser")]
1784impl_debug_as_display!(StyleOverflowWrapParseError<'a>);
1785#[cfg(feature = "parser")]
1786impl_display! { StyleOverflowWrapParseError<'a>, {
1787 InvalidValue(e) => format!("Invalid overflow-wrap value: \"{}\"", e.0),
1788}}
1789#[cfg(feature = "parser")]
1790impl_from!(InvalidValueErr<'a>, StyleOverflowWrapParseError::InvalidValue);
1791
1792#[cfg(feature = "parser")]
1793#[derive(Debug, Clone, PartialEq)]
1794#[repr(C, u8)]
1795pub enum StyleOverflowWrapParseErrorOwned {
1796 InvalidValue(InvalidValueErrOwned),
1797}
1798
1799#[cfg(feature = "parser")]
1800impl<'a> StyleOverflowWrapParseError<'a> {
1801 pub fn to_contained(&self) -> StyleOverflowWrapParseErrorOwned {
1802 match self {
1803 Self::InvalidValue(e) => StyleOverflowWrapParseErrorOwned::InvalidValue(e.to_contained()),
1804 }
1805 }
1806}
1807
1808#[cfg(feature = "parser")]
1809impl StyleOverflowWrapParseErrorOwned {
1810 pub fn to_shared<'a>(&'a self) -> StyleOverflowWrapParseError<'a> {
1811 match self {
1812 Self::InvalidValue(e) => StyleOverflowWrapParseError::InvalidValue(e.to_shared()),
1813 }
1814 }
1815}
1816
1817#[cfg(feature = "parser")]
1818pub fn parse_style_overflow_wrap(input: &str) -> Result<StyleOverflowWrap, StyleOverflowWrapParseError<'_>> {
1819 match input.trim() {
1820 "normal" => Ok(StyleOverflowWrap::Normal),
1821 "anywhere" => Ok(StyleOverflowWrap::Anywhere),
1822 "break-word" => Ok(StyleOverflowWrap::BreakWord),
1823 other => Err(StyleOverflowWrapParseError::InvalidValue(InvalidValueErr(other))),
1824 }
1825}
1826
1827#[cfg(feature = "parser")]
1830#[derive(Clone, PartialEq)]
1831pub enum StyleTextAlignLastParseError<'a> {
1832 InvalidValue(InvalidValueErr<'a>),
1833}
1834#[cfg(feature = "parser")]
1835impl_debug_as_display!(StyleTextAlignLastParseError<'a>);
1836#[cfg(feature = "parser")]
1837impl_display! { StyleTextAlignLastParseError<'a>, {
1838 InvalidValue(e) => format!("Invalid text-align-last value: \"{}\"", e.0),
1839}}
1840#[cfg(feature = "parser")]
1841impl_from!(InvalidValueErr<'a>, StyleTextAlignLastParseError::InvalidValue);
1842
1843#[cfg(feature = "parser")]
1844#[derive(Debug, Clone, PartialEq)]
1845#[repr(C, u8)]
1846pub enum StyleTextAlignLastParseErrorOwned {
1847 InvalidValue(InvalidValueErrOwned),
1848}
1849
1850#[cfg(feature = "parser")]
1851impl<'a> StyleTextAlignLastParseError<'a> {
1852 pub fn to_contained(&self) -> StyleTextAlignLastParseErrorOwned {
1853 match self {
1854 Self::InvalidValue(e) => StyleTextAlignLastParseErrorOwned::InvalidValue(e.to_contained()),
1855 }
1856 }
1857}
1858
1859#[cfg(feature = "parser")]
1860impl StyleTextAlignLastParseErrorOwned {
1861 pub fn to_shared<'a>(&'a self) -> StyleTextAlignLastParseError<'a> {
1862 match self {
1863 Self::InvalidValue(e) => StyleTextAlignLastParseError::InvalidValue(e.to_shared()),
1864 }
1865 }
1866}
1867
1868#[cfg(feature = "parser")]
1869pub fn parse_style_text_align_last(input: &str) -> Result<StyleTextAlignLast, StyleTextAlignLastParseError<'_>> {
1870 match input.trim() {
1871 "auto" => Ok(StyleTextAlignLast::Auto),
1872 "start" => Ok(StyleTextAlignLast::Start),
1873 "end" => Ok(StyleTextAlignLast::End),
1874 "left" => Ok(StyleTextAlignLast::Left),
1875 "right" => Ok(StyleTextAlignLast::Right),
1876 "center" => Ok(StyleTextAlignLast::Center),
1877 "justify" => Ok(StyleTextAlignLast::Justify),
1878 other => Err(StyleTextAlignLastParseError::InvalidValue(InvalidValueErr(other))),
1879 }
1880}
1881
1882#[cfg(feature = "parser")]
1883#[derive(Clone, PartialEq)]
1884pub enum StyleDirectionParseError<'a> {
1885 InvalidValue(InvalidValueErr<'a>),
1886}
1887#[cfg(feature = "parser")]
1888impl_debug_as_display!(StyleDirectionParseError<'a>);
1889#[cfg(feature = "parser")]
1890impl_display! { StyleDirectionParseError<'a>, {
1891 InvalidValue(e) => format!("Invalid direction value: \"{}\"", e.0),
1892}}
1893#[cfg(feature = "parser")]
1894impl_from!(InvalidValueErr<'a>, StyleDirectionParseError::InvalidValue);
1895
1896#[cfg(feature = "parser")]
1897#[derive(Debug, Clone, PartialEq)]
1898#[repr(C, u8)]
1899pub enum StyleDirectionParseErrorOwned {
1900 InvalidValue(InvalidValueErrOwned),
1901}
1902
1903#[cfg(feature = "parser")]
1904impl<'a> StyleDirectionParseError<'a> {
1905 pub fn to_contained(&self) -> StyleDirectionParseErrorOwned {
1906 match self {
1907 Self::InvalidValue(e) => StyleDirectionParseErrorOwned::InvalidValue(e.to_contained()),
1908 }
1909 }
1910}
1911
1912#[cfg(feature = "parser")]
1913impl StyleDirectionParseErrorOwned {
1914 pub fn to_shared<'a>(&'a self) -> StyleDirectionParseError<'a> {
1915 match self {
1916 Self::InvalidValue(e) => StyleDirectionParseError::InvalidValue(e.to_shared()),
1917 }
1918 }
1919}
1920
1921#[cfg(feature = "parser")]
1922pub fn parse_style_direction(input: &str) -> Result<StyleDirection, StyleDirectionParseError<'_>> {
1923 match input.trim() {
1924 "ltr" => Ok(StyleDirection::Ltr),
1925 "rtl" => Ok(StyleDirection::Rtl),
1926 other => Err(StyleDirectionParseError::InvalidValue(InvalidValueErr(
1927 other,
1928 ))),
1929 }
1930}
1931
1932#[cfg(feature = "parser")]
1933#[derive(Clone, PartialEq)]
1934pub enum StyleUserSelectParseError<'a> {
1935 InvalidValue(InvalidValueErr<'a>),
1936}
1937#[cfg(feature = "parser")]
1938impl_debug_as_display!(StyleUserSelectParseError<'a>);
1939#[cfg(feature = "parser")]
1940impl_display! { StyleUserSelectParseError<'a>, {
1941 InvalidValue(e) => format!("Invalid user-select value: \"{}\"", e.0),
1942}}
1943#[cfg(feature = "parser")]
1944impl_from!(InvalidValueErr<'a>, StyleUserSelectParseError::InvalidValue);
1945
1946#[cfg(feature = "parser")]
1947#[derive(Debug, Clone, PartialEq)]
1948#[repr(C, u8)]
1949pub enum StyleUserSelectParseErrorOwned {
1950 InvalidValue(InvalidValueErrOwned),
1951}
1952
1953#[cfg(feature = "parser")]
1954impl<'a> StyleUserSelectParseError<'a> {
1955 pub fn to_contained(&self) -> StyleUserSelectParseErrorOwned {
1956 match self {
1957 Self::InvalidValue(e) => StyleUserSelectParseErrorOwned::InvalidValue(e.to_contained()),
1958 }
1959 }
1960}
1961
1962#[cfg(feature = "parser")]
1963impl StyleUserSelectParseErrorOwned {
1964 pub fn to_shared<'a>(&'a self) -> StyleUserSelectParseError<'a> {
1965 match self {
1966 Self::InvalidValue(e) => StyleUserSelectParseError::InvalidValue(e.to_shared()),
1967 }
1968 }
1969}
1970
1971#[cfg(feature = "parser")]
1972pub fn parse_style_user_select(input: &str) -> Result<StyleUserSelect, StyleUserSelectParseError<'_>> {
1973 match input.trim() {
1974 "auto" => Ok(StyleUserSelect::Auto),
1975 "text" => Ok(StyleUserSelect::Text),
1976 "none" => Ok(StyleUserSelect::None),
1977 "all" => Ok(StyleUserSelect::All),
1978 other => Err(StyleUserSelectParseError::InvalidValue(InvalidValueErr(
1979 other,
1980 ))),
1981 }
1982}
1983
1984#[cfg(feature = "parser")]
1985#[derive(Clone, PartialEq)]
1986pub enum StyleTextDecorationParseError<'a> {
1987 InvalidValue(InvalidValueErr<'a>),
1988}
1989#[cfg(feature = "parser")]
1990impl_debug_as_display!(StyleTextDecorationParseError<'a>);
1991#[cfg(feature = "parser")]
1992impl_display! { StyleTextDecorationParseError<'a>, {
1993 InvalidValue(e) => format!("Invalid text-decoration value: \"{}\"", e.0),
1994}}
1995#[cfg(feature = "parser")]
1996impl_from!(
1997 InvalidValueErr<'a>,
1998 StyleTextDecorationParseError::InvalidValue
1999);
2000
2001#[cfg(feature = "parser")]
2002#[derive(Debug, Clone, PartialEq)]
2003#[repr(C, u8)]
2004pub enum StyleTextDecorationParseErrorOwned {
2005 InvalidValue(InvalidValueErrOwned),
2006}
2007
2008#[cfg(feature = "parser")]
2009impl<'a> StyleTextDecorationParseError<'a> {
2010 pub fn to_contained(&self) -> StyleTextDecorationParseErrorOwned {
2011 match self {
2012 Self::InvalidValue(e) => {
2013 StyleTextDecorationParseErrorOwned::InvalidValue(e.to_contained())
2014 }
2015 }
2016 }
2017}
2018
2019#[cfg(feature = "parser")]
2020impl StyleTextDecorationParseErrorOwned {
2021 pub fn to_shared<'a>(&'a self) -> StyleTextDecorationParseError<'a> {
2022 match self {
2023 Self::InvalidValue(e) => StyleTextDecorationParseError::InvalidValue(e.to_shared()),
2024 }
2025 }
2026}
2027
2028#[cfg(feature = "parser")]
2029pub fn parse_style_text_decoration(
2030 input: &str,
2031) -> Result<StyleTextDecoration, StyleTextDecorationParseError<'_>> {
2032 match input.trim() {
2033 "none" => Ok(StyleTextDecoration::None),
2034 "underline" => Ok(StyleTextDecoration::Underline),
2035 "overline" => Ok(StyleTextDecoration::Overline),
2036 "line-through" => Ok(StyleTextDecoration::LineThrough),
2037 other => Err(StyleTextDecorationParseError::InvalidValue(
2038 InvalidValueErr(other),
2039 )),
2040 }
2041}
2042
2043#[cfg(feature = "parser")]
2044#[derive(Clone, PartialEq)]
2045pub enum StyleVerticalAlignParseError<'a> {
2046 InvalidValue(InvalidValueErr<'a>),
2047}
2048#[cfg(feature = "parser")]
2049impl_debug_as_display!(StyleVerticalAlignParseError<'a>);
2050#[cfg(feature = "parser")]
2051impl_display! { StyleVerticalAlignParseError<'a>, {
2052 InvalidValue(e) => format!("Invalid vertical-align value: \"{}\"", e.0),
2053}}
2054#[cfg(feature = "parser")]
2055impl_from!(
2056 InvalidValueErr<'a>,
2057 StyleVerticalAlignParseError::InvalidValue
2058);
2059
2060#[cfg(feature = "parser")]
2061#[derive(Debug, Clone, PartialEq)]
2062#[repr(C, u8)]
2063pub enum StyleVerticalAlignParseErrorOwned {
2064 InvalidValue(InvalidValueErrOwned),
2065}
2066
2067#[cfg(feature = "parser")]
2068impl<'a> StyleVerticalAlignParseError<'a> {
2069 pub fn to_contained(&self) -> StyleVerticalAlignParseErrorOwned {
2070 match self {
2071 Self::InvalidValue(e) => {
2072 StyleVerticalAlignParseErrorOwned::InvalidValue(e.to_contained())
2073 }
2074 }
2075 }
2076}
2077
2078#[cfg(feature = "parser")]
2079impl StyleVerticalAlignParseErrorOwned {
2080 pub fn to_shared<'a>(&'a self) -> StyleVerticalAlignParseError<'a> {
2081 match self {
2082 Self::InvalidValue(e) => StyleVerticalAlignParseError::InvalidValue(e.to_shared()),
2083 }
2084 }
2085}
2086
2087#[cfg(feature = "parser")]
2088pub fn parse_style_vertical_align(
2089 input: &str,
2090) -> Result<StyleVerticalAlign, StyleVerticalAlignParseError<'_>> {
2091 match input.trim() {
2092 "baseline" => Ok(StyleVerticalAlign::Baseline),
2093 "top" => Ok(StyleVerticalAlign::Top),
2094 "middle" => Ok(StyleVerticalAlign::Middle),
2095 "bottom" => Ok(StyleVerticalAlign::Bottom),
2096 "sub" => Ok(StyleVerticalAlign::Sub),
2097 "super" => Ok(StyleVerticalAlign::Superscript),
2098 "text-top" => Ok(StyleVerticalAlign::TextTop),
2099 "text-bottom" => Ok(StyleVerticalAlign::TextBottom),
2100 other if other.ends_with('%') => {
2101 let num_str = other.trim_end_matches('%').trim();
2102 match num_str.parse::<f32>() {
2103 Ok(val) => Ok(StyleVerticalAlign::Percentage(PercentageValue::new(val))),
2104 Err(_) => Err(StyleVerticalAlignParseError::InvalidValue(InvalidValueErr(other))),
2105 }
2106 }
2107 other => match crate::props::basic::pixel::parse_pixel_value(other) {
2108 Ok(pv) => Ok(StyleVerticalAlign::Length(pv)),
2109 Err(_) => Err(StyleVerticalAlignParseError::InvalidValue(InvalidValueErr(
2110 other,
2111 ))),
2112 },
2113 }
2114}
2115
2116#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2119#[repr(C)]
2120pub struct CaretColor {
2121 pub inner: ColorU,
2122}
2123
2124impl Default for CaretColor {
2125 fn default() -> Self {
2126 Self {
2127 inner: ColorU::BLACK,
2128 }
2129 }
2130}
2131
2132impl PrintAsCssValue for CaretColor {
2133 fn print_as_css_value(&self) -> String {
2134 self.inner.to_hash()
2135 }
2136}
2137
2138impl crate::format_rust_code::FormatAsRustCode for CaretColor {
2139 fn format_as_rust_code(&self, _tabs: usize) -> String {
2140 format!(
2141 "CaretColor {{ inner: {} }}",
2142 crate::format_rust_code::format_color_value(&self.inner)
2143 )
2144 }
2145}
2146
2147#[cfg(feature = "parser")]
2148pub fn parse_caret_color(input: &str) -> Result<CaretColor, CssColorParseError<'_>> {
2149 parse_css_color(input).map(|inner| CaretColor { inner })
2150}
2151
2152#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2155#[repr(C)]
2156pub struct CaretAnimationDuration {
2157 pub inner: CssDuration,
2158}
2159
2160impl Default for CaretAnimationDuration {
2161 fn default() -> Self {
2162 Self {
2163 inner: CssDuration { inner: 500 },
2164 } }
2166}
2167
2168impl PrintAsCssValue for CaretAnimationDuration {
2169 fn print_as_css_value(&self) -> String {
2170 self.inner.print_as_css_value()
2171 }
2172}
2173
2174impl crate::format_rust_code::FormatAsRustCode for CaretAnimationDuration {
2175 fn format_as_rust_code(&self, _tabs: usize) -> String {
2176 format!(
2177 "CaretAnimationDuration {{ inner: {} }}",
2178 self.inner.format_as_rust_code(0)
2179 )
2180 }
2181}
2182
2183#[cfg(feature = "parser")]
2184pub fn parse_caret_animation_duration(
2185 input: &str,
2186) -> Result<CaretAnimationDuration, DurationParseError<'_>> {
2187 use crate::props::basic::parse_duration;
2188
2189 parse_duration(input).map(|inner| CaretAnimationDuration { inner })
2190}
2191
2192#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2197#[repr(C)]
2198pub struct CaretWidth {
2199 pub inner: PixelValue,
2200}
2201
2202impl Default for CaretWidth {
2203 fn default() -> Self {
2204 Self {
2205 inner: PixelValue::px(2.0), }
2207 }
2208}
2209
2210impl PrintAsCssValue for CaretWidth {
2211 fn print_as_css_value(&self) -> String {
2212 self.inner.print_as_css_value()
2213 }
2214}
2215
2216impl crate::format_rust_code::FormatAsRustCode for CaretWidth {
2217 fn format_as_rust_code(&self, _tabs: usize) -> String {
2218 format!(
2219 "CaretWidth {{ inner: {} }}",
2220 self.inner.format_as_rust_code(0)
2221 )
2222 }
2223}
2224
2225#[cfg(feature = "parser")]
2226pub fn parse_caret_width(input: &str) -> Result<CaretWidth, CssPixelValueParseError<'_>> {
2227 use crate::props::basic::pixel::parse_pixel_value;
2228
2229 parse_pixel_value(input).map(|inner| CaretWidth { inner })
2230}
2231
2232impl From<StyleUserSelect> for crate::props::property::CssProperty {
2235 fn from(value: StyleUserSelect) -> Self {
2236 use crate::props::property::CssProperty;
2237 CssProperty::user_select(value)
2238 }
2239}
2240
2241impl From<StyleTextDecoration> for crate::props::property::CssProperty {
2242 fn from(value: StyleTextDecoration) -> Self {
2243 use crate::props::property::CssProperty;
2244 CssProperty::text_decoration(value)
2245 }
2246}
2247
2248#[cfg(all(test, feature = "parser"))]
2249mod tests {
2250 use super::*;
2251 use crate::props::basic::{color::ColorU, length::PercentageValue, pixel::PixelValue};
2252
2253 #[test]
2254 fn test_parse_style_text_color() {
2255 assert_eq!(
2256 parse_style_text_color("red").unwrap().inner,
2257 ColorU::new_rgb(255, 0, 0)
2258 );
2259 assert_eq!(
2260 parse_style_text_color("#aabbcc").unwrap().inner,
2261 ColorU::new_rgb(170, 187, 204)
2262 );
2263 assert!(parse_style_text_color("not-a-color").is_err());
2264 }
2265
2266 #[test]
2267 fn test_parse_style_text_align() {
2268 assert_eq!(
2269 parse_style_text_align("left").unwrap(),
2270 StyleTextAlign::Left
2271 );
2272 assert_eq!(
2273 parse_style_text_align("center").unwrap(),
2274 StyleTextAlign::Center
2275 );
2276 assert_eq!(
2277 parse_style_text_align("right").unwrap(),
2278 StyleTextAlign::Right
2279 );
2280 assert_eq!(
2281 parse_style_text_align("justify").unwrap(),
2282 StyleTextAlign::Justify
2283 );
2284 assert_eq!(
2285 parse_style_text_align("start").unwrap(),
2286 StyleTextAlign::Start
2287 );
2288 assert_eq!(parse_style_text_align("end").unwrap(), StyleTextAlign::End);
2289 assert!(parse_style_text_align("middle").is_err());
2290 }
2291
2292 #[test]
2293 fn test_parse_spacing() {
2294 assert_eq!(
2295 parse_style_letter_spacing("2px").unwrap().inner,
2296 PixelValue::px(2.0)
2297 );
2298 assert_eq!(
2299 parse_style_letter_spacing("-0.1em").unwrap().inner,
2300 PixelValue::em(-0.1)
2301 );
2302 assert_eq!(
2303 parse_style_word_spacing("0.5em").unwrap().inner,
2304 PixelValue::em(0.5)
2305 );
2306 }
2307
2308 #[test]
2309 fn test_parse_line_height() {
2310 assert_eq!(
2311 parse_style_line_height("1.5").unwrap().inner,
2312 PercentageValue::new(150.0)
2313 );
2314 assert_eq!(
2315 parse_style_line_height("120%").unwrap().inner,
2316 PercentageValue::new(120.0)
2317 );
2318 assert_eq!(
2320 parse_style_line_height("20px").unwrap().inner,
2321 PercentageValue::new(-20.0 * 100.0)
2322 );
2323 }
2324
2325 #[test]
2326 fn test_parse_tab_size() {
2327 assert_eq!(
2329 parse_style_tab_size("4").unwrap().inner,
2330 PixelValue::em(4.0)
2331 );
2332 assert_eq!(
2333 parse_style_tab_size("20px").unwrap().inner,
2334 PixelValue::px(20.0)
2335 );
2336 }
2337
2338 #[test]
2339 fn test_parse_white_space() {
2340 assert_eq!(
2341 parse_style_white_space("normal").unwrap(),
2342 StyleWhiteSpace::Normal
2343 );
2344 assert_eq!(
2345 parse_style_white_space("pre").unwrap(),
2346 StyleWhiteSpace::Pre
2347 );
2348 assert_eq!(
2349 parse_style_white_space("nowrap").unwrap(),
2350 StyleWhiteSpace::Nowrap
2351 );
2352 assert_eq!(
2353 parse_style_white_space("pre-wrap").unwrap(),
2354 StyleWhiteSpace::PreWrap
2355 );
2356 }
2357}
2358
2359#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2365#[repr(C)]
2366#[derive(Default)]
2367pub enum StyleUnicodeBidi {
2368 #[default]
2370 Normal,
2371 Embed,
2373 Isolate,
2375 BidiOverride,
2377 IsolateOverride,
2379 Plaintext,
2381}
2382impl_option!(
2383 StyleUnicodeBidi,
2384 OptionStyleUnicodeBidi,
2385 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
2386);
2387impl PrintAsCssValue for StyleUnicodeBidi {
2388 fn print_as_css_value(&self) -> String {
2389 String::from(match self {
2390 StyleUnicodeBidi::Normal => "normal",
2391 StyleUnicodeBidi::Embed => "embed",
2392 StyleUnicodeBidi::Isolate => "isolate",
2393 StyleUnicodeBidi::BidiOverride => "bidi-override",
2394 StyleUnicodeBidi::IsolateOverride => "isolate-override",
2395 StyleUnicodeBidi::Plaintext => "plaintext",
2396 })
2397 }
2398}
2399
2400#[cfg(feature = "parser")]
2401#[derive(Clone, PartialEq)]
2402pub enum StyleUnicodeBidiParseError<'a> {
2403 InvalidValue(InvalidValueErr<'a>),
2404}
2405#[cfg(feature = "parser")]
2406impl_debug_as_display!(StyleUnicodeBidiParseError<'a>);
2407#[cfg(feature = "parser")]
2408impl_display! { StyleUnicodeBidiParseError<'a>, {
2409 InvalidValue(e) => format!("Invalid unicode-bidi value: \"{}\"", e.0),
2410}}
2411#[cfg(feature = "parser")]
2412impl_from!(InvalidValueErr<'a>, StyleUnicodeBidiParseError::InvalidValue);
2413
2414#[cfg(feature = "parser")]
2415#[derive(Debug, Clone, PartialEq)]
2416#[repr(C, u8)]
2417pub enum StyleUnicodeBidiParseErrorOwned {
2418 InvalidValue(InvalidValueErrOwned),
2419}
2420
2421#[cfg(feature = "parser")]
2422impl<'a> StyleUnicodeBidiParseError<'a> {
2423 pub fn to_contained(&self) -> StyleUnicodeBidiParseErrorOwned {
2424 match self {
2425 Self::InvalidValue(e) => StyleUnicodeBidiParseErrorOwned::InvalidValue(e.to_contained()),
2426 }
2427 }
2428}
2429
2430#[cfg(feature = "parser")]
2431impl StyleUnicodeBidiParseErrorOwned {
2432 pub fn to_shared<'a>(&'a self) -> StyleUnicodeBidiParseError<'a> {
2433 match self {
2434 Self::InvalidValue(e) => StyleUnicodeBidiParseError::InvalidValue(e.to_shared()),
2435 }
2436 }
2437}
2438
2439#[cfg(feature = "parser")]
2440pub fn parse_style_unicode_bidi(input: &str) -> Result<StyleUnicodeBidi, StyleUnicodeBidiParseError<'_>> {
2441 match input.trim() {
2442 "normal" => Ok(StyleUnicodeBidi::Normal),
2443 "embed" => Ok(StyleUnicodeBidi::Embed),
2444 "isolate" => Ok(StyleUnicodeBidi::Isolate),
2445 "bidi-override" => Ok(StyleUnicodeBidi::BidiOverride),
2446 "isolate-override" => Ok(StyleUnicodeBidi::IsolateOverride),
2447 "plaintext" => Ok(StyleUnicodeBidi::Plaintext),
2448 other => Err(StyleUnicodeBidiParseError::InvalidValue(InvalidValueErr(other))),
2449 }
2450}
2451
2452#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2458#[repr(C)]
2459#[derive(Default)]
2460pub enum StyleTextBoxTrim {
2461 #[default]
2463 None,
2464 TrimStart,
2466 TrimEnd,
2468 TrimBoth,
2470}
2471impl_option!(
2472 StyleTextBoxTrim,
2473 OptionStyleTextBoxTrim,
2474 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
2475);
2476impl PrintAsCssValue for StyleTextBoxTrim {
2477 fn print_as_css_value(&self) -> String {
2478 String::from(match self {
2479 StyleTextBoxTrim::None => "none",
2480 StyleTextBoxTrim::TrimStart => "trim-start",
2481 StyleTextBoxTrim::TrimEnd => "trim-end",
2482 StyleTextBoxTrim::TrimBoth => "trim-both",
2483 })
2484 }
2485}
2486
2487#[cfg(feature = "parser")]
2488#[derive(Clone, PartialEq)]
2489pub enum StyleTextBoxTrimParseError<'a> {
2490 InvalidValue(InvalidValueErr<'a>),
2491}
2492#[cfg(feature = "parser")]
2493impl_debug_as_display!(StyleTextBoxTrimParseError<'a>);
2494#[cfg(feature = "parser")]
2495impl_display! { StyleTextBoxTrimParseError<'a>, {
2496 InvalidValue(e) => format!("Invalid text-box-trim value: \"{}\"", e.0),
2497}}
2498#[cfg(feature = "parser")]
2499impl_from!(InvalidValueErr<'a>, StyleTextBoxTrimParseError::InvalidValue);
2500
2501#[cfg(feature = "parser")]
2502#[derive(Debug, Clone, PartialEq)]
2503#[repr(C, u8)]
2504pub enum StyleTextBoxTrimParseErrorOwned {
2505 InvalidValue(InvalidValueErrOwned),
2506}
2507
2508#[cfg(feature = "parser")]
2509impl<'a> StyleTextBoxTrimParseError<'a> {
2510 pub fn to_contained(&self) -> StyleTextBoxTrimParseErrorOwned {
2511 match self {
2512 Self::InvalidValue(e) => StyleTextBoxTrimParseErrorOwned::InvalidValue(e.to_contained()),
2513 }
2514 }
2515}
2516
2517#[cfg(feature = "parser")]
2518impl StyleTextBoxTrimParseErrorOwned {
2519 pub fn to_shared<'a>(&'a self) -> StyleTextBoxTrimParseError<'a> {
2520 match self {
2521 Self::InvalidValue(e) => StyleTextBoxTrimParseError::InvalidValue(e.to_shared()),
2522 }
2523 }
2524}
2525
2526#[cfg(feature = "parser")]
2527pub fn parse_style_text_box_trim(input: &str) -> Result<StyleTextBoxTrim, StyleTextBoxTrimParseError<'_>> {
2528 match input.trim() {
2529 "none" => Ok(StyleTextBoxTrim::None),
2530 "trim-start" => Ok(StyleTextBoxTrim::TrimStart),
2531 "trim-end" => Ok(StyleTextBoxTrim::TrimEnd),
2532 "trim-both" => Ok(StyleTextBoxTrim::TrimBoth),
2533 other => Err(StyleTextBoxTrimParseError::InvalidValue(InvalidValueErr(other))),
2534 }
2535}
2536
2537#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2545#[repr(C)]
2546#[derive(Default)]
2547pub enum StyleTextBoxEdge {
2548 #[default]
2551 Auto,
2552 TextEdge,
2554 CapHeight,
2556 ExHeight,
2558}
2559impl_option!(
2560 StyleTextBoxEdge,
2561 OptionStyleTextBoxEdge,
2562 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
2563);
2564impl PrintAsCssValue for StyleTextBoxEdge {
2565 fn print_as_css_value(&self) -> String {
2566 String::from(match self {
2567 StyleTextBoxEdge::Auto => "auto",
2568 StyleTextBoxEdge::TextEdge => "text",
2569 StyleTextBoxEdge::CapHeight => "cap",
2570 StyleTextBoxEdge::ExHeight => "ex",
2571 })
2572 }
2573}
2574
2575#[cfg(feature = "parser")]
2576#[derive(Clone, PartialEq)]
2577pub enum StyleTextBoxEdgeParseError<'a> {
2578 InvalidValue(InvalidValueErr<'a>),
2579}
2580#[cfg(feature = "parser")]
2581impl_debug_as_display!(StyleTextBoxEdgeParseError<'a>);
2582#[cfg(feature = "parser")]
2583impl_display! { StyleTextBoxEdgeParseError<'a>, {
2584 InvalidValue(e) => format!("Invalid text-box-edge value: \"{}\"", e.0),
2585}}
2586#[cfg(feature = "parser")]
2587impl_from!(InvalidValueErr<'a>, StyleTextBoxEdgeParseError::InvalidValue);
2588
2589#[cfg(feature = "parser")]
2590#[derive(Debug, Clone, PartialEq)]
2591#[repr(C, u8)]
2592pub enum StyleTextBoxEdgeParseErrorOwned {
2593 InvalidValue(InvalidValueErrOwned),
2594}
2595
2596#[cfg(feature = "parser")]
2597impl<'a> StyleTextBoxEdgeParseError<'a> {
2598 pub fn to_contained(&self) -> StyleTextBoxEdgeParseErrorOwned {
2599 match self {
2600 Self::InvalidValue(e) => StyleTextBoxEdgeParseErrorOwned::InvalidValue(e.to_contained()),
2601 }
2602 }
2603}
2604
2605#[cfg(feature = "parser")]
2606impl StyleTextBoxEdgeParseErrorOwned {
2607 pub fn to_shared<'a>(&'a self) -> StyleTextBoxEdgeParseError<'a> {
2608 match self {
2609 Self::InvalidValue(e) => StyleTextBoxEdgeParseError::InvalidValue(e.to_shared()),
2610 }
2611 }
2612}
2613
2614#[cfg(feature = "parser")]
2615pub fn parse_style_text_box_edge(input: &str) -> Result<StyleTextBoxEdge, StyleTextBoxEdgeParseError<'_>> {
2616 match input.trim() {
2617 "auto" => Ok(StyleTextBoxEdge::Auto),
2618 "text" => Ok(StyleTextBoxEdge::TextEdge),
2619 "cap" => Ok(StyleTextBoxEdge::CapHeight),
2620 "ex" => Ok(StyleTextBoxEdge::ExHeight),
2621 other => Err(StyleTextBoxEdgeParseError::InvalidValue(InvalidValueErr(other))),
2622 }
2623}
2624
2625#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2631#[repr(C)]
2632#[derive(Default)]
2633pub enum StyleDominantBaseline {
2634 #[default]
2636 Auto,
2637 TextBottom,
2639 Alphabetic,
2641 Ideographic,
2643 Middle,
2645 Central,
2647 Mathematical,
2649 Hanging,
2651 TextTop,
2653}
2654impl_option!(
2655 StyleDominantBaseline,
2656 OptionStyleDominantBaseline,
2657 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
2658);
2659impl PrintAsCssValue for StyleDominantBaseline {
2660 fn print_as_css_value(&self) -> String {
2661 String::from(match self {
2662 StyleDominantBaseline::Auto => "auto",
2663 StyleDominantBaseline::TextBottom => "text-bottom",
2664 StyleDominantBaseline::Alphabetic => "alphabetic",
2665 StyleDominantBaseline::Ideographic => "ideographic",
2666 StyleDominantBaseline::Middle => "middle",
2667 StyleDominantBaseline::Central => "central",
2668 StyleDominantBaseline::Mathematical => "mathematical",
2669 StyleDominantBaseline::Hanging => "hanging",
2670 StyleDominantBaseline::TextTop => "text-top",
2671 })
2672 }
2673}
2674
2675#[cfg(feature = "parser")]
2676#[derive(Clone, PartialEq)]
2677pub enum StyleDominantBaselineParseError<'a> {
2678 InvalidValue(InvalidValueErr<'a>),
2679}
2680#[cfg(feature = "parser")]
2681impl_debug_as_display!(StyleDominantBaselineParseError<'a>);
2682#[cfg(feature = "parser")]
2683impl_display! { StyleDominantBaselineParseError<'a>, {
2684 InvalidValue(e) => format!("Invalid dominant-baseline value: \"{}\"", e.0),
2685}}
2686#[cfg(feature = "parser")]
2687impl_from!(InvalidValueErr<'a>, StyleDominantBaselineParseError::InvalidValue);
2688
2689#[cfg(feature = "parser")]
2690#[derive(Debug, Clone, PartialEq)]
2691#[repr(C, u8)]
2692pub enum StyleDominantBaselineParseErrorOwned {
2693 InvalidValue(InvalidValueErrOwned),
2694}
2695
2696#[cfg(feature = "parser")]
2697impl<'a> StyleDominantBaselineParseError<'a> {
2698 pub fn to_contained(&self) -> StyleDominantBaselineParseErrorOwned {
2699 match self {
2700 Self::InvalidValue(e) => StyleDominantBaselineParseErrorOwned::InvalidValue(e.to_contained()),
2701 }
2702 }
2703}
2704
2705#[cfg(feature = "parser")]
2706impl StyleDominantBaselineParseErrorOwned {
2707 pub fn to_shared<'a>(&'a self) -> StyleDominantBaselineParseError<'a> {
2708 match self {
2709 Self::InvalidValue(e) => StyleDominantBaselineParseError::InvalidValue(e.to_shared()),
2710 }
2711 }
2712}
2713
2714#[cfg(feature = "parser")]
2715pub fn parse_style_dominant_baseline(input: &str) -> Result<StyleDominantBaseline, StyleDominantBaselineParseError<'_>> {
2716 match input.trim() {
2717 "auto" => Ok(StyleDominantBaseline::Auto),
2718 "text-bottom" => Ok(StyleDominantBaseline::TextBottom),
2719 "alphabetic" => Ok(StyleDominantBaseline::Alphabetic),
2720 "ideographic" => Ok(StyleDominantBaseline::Ideographic),
2721 "middle" => Ok(StyleDominantBaseline::Middle),
2722 "central" => Ok(StyleDominantBaseline::Central),
2723 "mathematical" => Ok(StyleDominantBaseline::Mathematical),
2724 "hanging" => Ok(StyleDominantBaseline::Hanging),
2725 "text-top" => Ok(StyleDominantBaseline::TextTop),
2726 other => Err(StyleDominantBaselineParseError::InvalidValue(InvalidValueErr(other))),
2727 }
2728}
2729
2730#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2740#[repr(C)]
2741#[derive(Default)]
2742pub enum StyleAlignmentBaseline {
2743 #[default]
2745 Baseline,
2746 TextBottom,
2748 Alphabetic,
2750 Ideographic,
2752 Middle,
2754 Central,
2756 Mathematical,
2758 TextTop,
2760}
2761impl_option!(
2762 StyleAlignmentBaseline,
2763 OptionStyleAlignmentBaseline,
2764 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
2765);
2766impl PrintAsCssValue for StyleAlignmentBaseline {
2767 fn print_as_css_value(&self) -> String {
2768 String::from(match self {
2769 StyleAlignmentBaseline::Baseline => "baseline",
2770 StyleAlignmentBaseline::TextBottom => "text-bottom",
2771 StyleAlignmentBaseline::Alphabetic => "alphabetic",
2772 StyleAlignmentBaseline::Ideographic => "ideographic",
2773 StyleAlignmentBaseline::Middle => "middle",
2774 StyleAlignmentBaseline::Central => "central",
2775 StyleAlignmentBaseline::Mathematical => "mathematical",
2776 StyleAlignmentBaseline::TextTop => "text-top",
2777 })
2778 }
2779}
2780
2781#[cfg(feature = "parser")]
2782#[derive(Clone, PartialEq)]
2783pub enum StyleAlignmentBaselineParseError<'a> {
2784 InvalidValue(InvalidValueErr<'a>),
2785}
2786#[cfg(feature = "parser")]
2787impl_debug_as_display!(StyleAlignmentBaselineParseError<'a>);
2788#[cfg(feature = "parser")]
2789impl_display! { StyleAlignmentBaselineParseError<'a>, {
2790 InvalidValue(e) => format!("Invalid alignment-baseline value: \"{}\"", e.0),
2791}}
2792#[cfg(feature = "parser")]
2793impl_from!(InvalidValueErr<'a>, StyleAlignmentBaselineParseError::InvalidValue);
2794
2795#[cfg(feature = "parser")]
2796#[derive(Debug, Clone, PartialEq)]
2797#[repr(C, u8)]
2798pub enum StyleAlignmentBaselineParseErrorOwned {
2799 InvalidValue(InvalidValueErrOwned),
2800}
2801
2802#[cfg(feature = "parser")]
2803impl<'a> StyleAlignmentBaselineParseError<'a> {
2804 pub fn to_contained(&self) -> StyleAlignmentBaselineParseErrorOwned {
2805 match self {
2806 Self::InvalidValue(e) => StyleAlignmentBaselineParseErrorOwned::InvalidValue(e.to_contained()),
2807 }
2808 }
2809}
2810
2811#[cfg(feature = "parser")]
2812impl StyleAlignmentBaselineParseErrorOwned {
2813 pub fn to_shared<'a>(&'a self) -> StyleAlignmentBaselineParseError<'a> {
2814 match self {
2815 Self::InvalidValue(e) => StyleAlignmentBaselineParseError::InvalidValue(e.to_shared()),
2816 }
2817 }
2818}
2819
2820#[cfg(feature = "parser")]
2821pub fn parse_style_alignment_baseline(input: &str) -> Result<StyleAlignmentBaseline, StyleAlignmentBaselineParseError<'_>> {
2822 match input.trim() {
2823 "baseline" => Ok(StyleAlignmentBaseline::Baseline),
2824 "text-bottom" => Ok(StyleAlignmentBaseline::TextBottom),
2825 "alphabetic" => Ok(StyleAlignmentBaseline::Alphabetic),
2826 "ideographic" => Ok(StyleAlignmentBaseline::Ideographic),
2827 "middle" => Ok(StyleAlignmentBaseline::Middle),
2828 "central" => Ok(StyleAlignmentBaseline::Central),
2829 "mathematical" => Ok(StyleAlignmentBaseline::Mathematical),
2830 "text-top" => Ok(StyleAlignmentBaseline::TextTop),
2831 other => Err(StyleAlignmentBaselineParseError::InvalidValue(InvalidValueErr(other))),
2832 }
2833}
2834
2835#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2841#[repr(C)]
2842#[derive(Default)]
2843pub enum StyleInitialLetterAlign {
2844 #[default]
2846 Auto,
2847 Alphabetic,
2849 Hanging,
2851 Ideographic,
2853}
2854impl_option!(
2855 StyleInitialLetterAlign,
2856 OptionStyleInitialLetterAlign,
2857 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
2858);
2859impl PrintAsCssValue for StyleInitialLetterAlign {
2860 fn print_as_css_value(&self) -> String {
2861 String::from(match self {
2862 StyleInitialLetterAlign::Auto => "auto",
2863 StyleInitialLetterAlign::Alphabetic => "alphabetic",
2864 StyleInitialLetterAlign::Hanging => "hanging",
2865 StyleInitialLetterAlign::Ideographic => "ideographic",
2866 })
2867 }
2868}
2869
2870#[cfg(feature = "parser")]
2871#[derive(Clone, PartialEq)]
2872pub enum StyleInitialLetterAlignParseError<'a> {
2873 InvalidValue(InvalidValueErr<'a>),
2874}
2875#[cfg(feature = "parser")]
2876impl_debug_as_display!(StyleInitialLetterAlignParseError<'a>);
2877#[cfg(feature = "parser")]
2878impl_display! { StyleInitialLetterAlignParseError<'a>, {
2879 InvalidValue(e) => format!("Invalid initial-letter-align value: \"{}\"", e.0),
2880}}
2881#[cfg(feature = "parser")]
2882impl_from!(InvalidValueErr<'a>, StyleInitialLetterAlignParseError::InvalidValue);
2883
2884#[cfg(feature = "parser")]
2885#[derive(Debug, Clone, PartialEq)]
2886#[repr(C, u8)]
2887pub enum StyleInitialLetterAlignParseErrorOwned {
2888 InvalidValue(InvalidValueErrOwned),
2889}
2890
2891#[cfg(feature = "parser")]
2892impl<'a> StyleInitialLetterAlignParseError<'a> {
2893 pub fn to_contained(&self) -> StyleInitialLetterAlignParseErrorOwned {
2894 match self {
2895 Self::InvalidValue(e) => StyleInitialLetterAlignParseErrorOwned::InvalidValue(e.to_contained()),
2896 }
2897 }
2898}
2899
2900#[cfg(feature = "parser")]
2901impl StyleInitialLetterAlignParseErrorOwned {
2902 pub fn to_shared<'a>(&'a self) -> StyleInitialLetterAlignParseError<'a> {
2903 match self {
2904 Self::InvalidValue(e) => StyleInitialLetterAlignParseError::InvalidValue(e.to_shared()),
2905 }
2906 }
2907}
2908
2909#[cfg(feature = "parser")]
2910pub fn parse_style_initial_letter_align(input: &str) -> Result<StyleInitialLetterAlign, StyleInitialLetterAlignParseError<'_>> {
2911 match input.trim() {
2912 "auto" => Ok(StyleInitialLetterAlign::Auto),
2913 "alphabetic" => Ok(StyleInitialLetterAlign::Alphabetic),
2914 "hanging" => Ok(StyleInitialLetterAlign::Hanging),
2915 "ideographic" => Ok(StyleInitialLetterAlign::Ideographic),
2916 other => Err(StyleInitialLetterAlignParseError::InvalidValue(InvalidValueErr(other))),
2917 }
2918}
2919
2920#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2926#[repr(C)]
2927#[derive(Default)]
2928pub enum StyleInitialLetterWrap {
2929 #[default]
2931 None,
2932 First,
2934 All,
2936 Grid,
2938}
2939impl_option!(
2940 StyleInitialLetterWrap,
2941 OptionStyleInitialLetterWrap,
2942 [Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash]
2943);
2944impl PrintAsCssValue for StyleInitialLetterWrap {
2945 fn print_as_css_value(&self) -> String {
2946 String::from(match self {
2947 StyleInitialLetterWrap::None => "none",
2948 StyleInitialLetterWrap::First => "first",
2949 StyleInitialLetterWrap::All => "all",
2950 StyleInitialLetterWrap::Grid => "grid",
2951 })
2952 }
2953}
2954
2955#[cfg(feature = "parser")]
2956#[derive(Clone, PartialEq)]
2957pub enum StyleInitialLetterWrapParseError<'a> {
2958 InvalidValue(InvalidValueErr<'a>),
2959}
2960#[cfg(feature = "parser")]
2961impl_debug_as_display!(StyleInitialLetterWrapParseError<'a>);
2962#[cfg(feature = "parser")]
2963impl_display! { StyleInitialLetterWrapParseError<'a>, {
2964 InvalidValue(e) => format!("Invalid initial-letter-wrap value: \"{}\"", e.0),
2965}}
2966#[cfg(feature = "parser")]
2967impl_from!(InvalidValueErr<'a>, StyleInitialLetterWrapParseError::InvalidValue);
2968
2969#[cfg(feature = "parser")]
2970#[derive(Debug, Clone, PartialEq)]
2971#[repr(C, u8)]
2972pub enum StyleInitialLetterWrapParseErrorOwned {
2973 InvalidValue(InvalidValueErrOwned),
2974}
2975
2976#[cfg(feature = "parser")]
2977impl<'a> StyleInitialLetterWrapParseError<'a> {
2978 pub fn to_contained(&self) -> StyleInitialLetterWrapParseErrorOwned {
2979 match self {
2980 Self::InvalidValue(e) => StyleInitialLetterWrapParseErrorOwned::InvalidValue(e.to_contained()),
2981 }
2982 }
2983}
2984
2985#[cfg(feature = "parser")]
2986impl StyleInitialLetterWrapParseErrorOwned {
2987 pub fn to_shared<'a>(&'a self) -> StyleInitialLetterWrapParseError<'a> {
2988 match self {
2989 Self::InvalidValue(e) => StyleInitialLetterWrapParseError::InvalidValue(e.to_shared()),
2990 }
2991 }
2992}
2993
2994#[cfg(feature = "parser")]
2995pub fn parse_style_initial_letter_wrap(input: &str) -> Result<StyleInitialLetterWrap, StyleInitialLetterWrapParseError<'_>> {
2996 match input.trim() {
2997 "none" => Ok(StyleInitialLetterWrap::None),
2998 "first" => Ok(StyleInitialLetterWrap::First),
2999 "all" => Ok(StyleInitialLetterWrap::All),
3000 "grid" => Ok(StyleInitialLetterWrap::Grid),
3001 other => Err(StyleInitialLetterWrapParseError::InvalidValue(InvalidValueErr(other))),
3002 }
3003}