1use alloc::string::{String, ToString};
4use core::num::ParseFloatError;
5
6use crate::{
7 format_rust_code::FormatAsRustCode,
8 props::{
9 basic::length::{parse_float_value, FloatValue},
10 formatter::PrintAsCssValue,
11 },
12};
13
14#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
20#[repr(C)]
21pub struct LayoutFlexGrow {
22 pub inner: FloatValue,
23}
24
25impl core::fmt::Debug for LayoutFlexGrow {
26 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
27 write!(f, "{}", self.inner.get())
28 }
29}
30
31impl Default for LayoutFlexGrow {
32 fn default() -> Self {
33 Self {
34 inner: FloatValue::const_new(0),
35 }
36 }
37}
38
39impl PrintAsCssValue for LayoutFlexGrow {
40 fn print_as_css_value(&self) -> String {
41 format!("{}", self.inner)
42 }
43}
44
45impl LayoutFlexGrow {
46 pub fn new(value: isize) -> Self {
47 Self {
48 inner: FloatValue::new(value as f32),
49 }
50 }
51
52 pub const fn const_new(value: isize) -> Self {
53 Self {
54 inner: FloatValue::const_new(value),
55 }
56 }
57
58 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
59 Self {
60 inner: self.inner.interpolate(&other.inner, t),
61 }
62 }
63}
64
65#[cfg(feature = "parser")]
66#[derive(Clone, PartialEq)]
67pub enum FlexGrowParseError<'a> {
68 ParseFloat(ParseFloatError, &'a str),
69 NegativeValue(&'a str),
70}
71
72#[cfg(feature = "parser")]
73impl_debug_as_display!(FlexGrowParseError<'a>);
74#[cfg(feature = "parser")]
75impl_display! { FlexGrowParseError<'a>, {
76 ParseFloat(e, s) => format!("Invalid flex-grow value: \"{}\". Reason: {}", s, e),
77 NegativeValue(s) => format!("Invalid flex-grow value: \"{}\". Flex-grow cannot be negative", s),
78}}
79
80#[cfg(feature = "parser")]
81#[derive(Debug, Clone, PartialEq)]
82pub enum FlexGrowParseErrorOwned {
83 ParseFloat(ParseFloatError, String),
84 NegativeValue(String),
85}
86
87#[cfg(feature = "parser")]
88impl<'a> FlexGrowParseError<'a> {
89 pub fn to_contained(&self) -> FlexGrowParseErrorOwned {
90 match self {
91 FlexGrowParseError::ParseFloat(e, s) => {
92 FlexGrowParseErrorOwned::ParseFloat(e.clone(), s.to_string())
93 }
94 FlexGrowParseError::NegativeValue(s) => {
95 FlexGrowParseErrorOwned::NegativeValue(s.to_string())
96 }
97 }
98 }
99}
100
101#[cfg(feature = "parser")]
102impl FlexGrowParseErrorOwned {
103 pub fn to_shared<'a>(&'a self) -> FlexGrowParseError<'a> {
104 match self {
105 FlexGrowParseErrorOwned::ParseFloat(e, s) => {
106 FlexGrowParseError::ParseFloat(e.clone(), s.as_str())
107 }
108 FlexGrowParseErrorOwned::NegativeValue(s) => {
109 FlexGrowParseError::NegativeValue(s.as_str())
110 }
111 }
112 }
113}
114
115#[cfg(feature = "parser")]
116pub fn parse_layout_flex_grow<'a>(
117 input: &'a str,
118) -> Result<LayoutFlexGrow, FlexGrowParseError<'a>> {
119 match parse_float_value(input) {
120 Ok(o) => {
121 if o.get() < 0.0 {
122 Err(FlexGrowParseError::NegativeValue(input))
123 } else {
124 Ok(LayoutFlexGrow { inner: o })
125 }
126 }
127 Err(e) => Err(FlexGrowParseError::ParseFloat(e, input)),
128 }
129}
130
131#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
137#[repr(C)]
138pub struct LayoutFlexShrink {
139 pub inner: FloatValue,
140}
141
142impl core::fmt::Debug for LayoutFlexShrink {
143 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
144 write!(f, "{}", self.inner.get())
145 }
146}
147
148impl Default for LayoutFlexShrink {
149 fn default() -> Self {
150 Self {
151 inner: FloatValue::const_new(1),
152 }
153 }
154}
155
156impl PrintAsCssValue for LayoutFlexShrink {
157 fn print_as_css_value(&self) -> String {
158 format!("{}", self.inner)
159 }
160}
161
162impl LayoutFlexShrink {
163 pub fn interpolate(&self, other: &Self, t: f32) -> Self {
164 Self {
165 inner: self.inner.interpolate(&other.inner, t),
166 }
167 }
168}
169
170#[cfg(feature = "parser")]
171#[derive(Clone, PartialEq)]
172pub enum FlexShrinkParseError<'a> {
173 ParseFloat(ParseFloatError, &'a str),
174 NegativeValue(&'a str),
175}
176
177#[cfg(feature = "parser")]
178impl_debug_as_display!(FlexShrinkParseError<'a>);
179#[cfg(feature = "parser")]
180impl_display! { FlexShrinkParseError<'a>, {
181 ParseFloat(e, s) => format!("Invalid flex-shrink value: \"{}\". Reason: {}", s, e),
182 NegativeValue(s) => format!("Invalid flex-shrink value: \"{}\". Flex-shrink cannot be negative", s),
183}}
184
185#[cfg(feature = "parser")]
186#[derive(Debug, Clone, PartialEq)]
187pub enum FlexShrinkParseErrorOwned {
188 ParseFloat(ParseFloatError, String),
189 NegativeValue(String),
190}
191
192#[cfg(feature = "parser")]
193impl<'a> FlexShrinkParseError<'a> {
194 pub fn to_contained(&self) -> FlexShrinkParseErrorOwned {
195 match self {
196 FlexShrinkParseError::ParseFloat(e, s) => {
197 FlexShrinkParseErrorOwned::ParseFloat(e.clone(), s.to_string())
198 }
199 FlexShrinkParseError::NegativeValue(s) => {
200 FlexShrinkParseErrorOwned::NegativeValue(s.to_string())
201 }
202 }
203 }
204}
205
206#[cfg(feature = "parser")]
207impl FlexShrinkParseErrorOwned {
208 pub fn to_shared<'a>(&'a self) -> FlexShrinkParseError<'a> {
209 match self {
210 FlexShrinkParseErrorOwned::ParseFloat(e, s) => {
211 FlexShrinkParseError::ParseFloat(e.clone(), s.as_str())
212 }
213 FlexShrinkParseErrorOwned::NegativeValue(s) => {
214 FlexShrinkParseError::NegativeValue(s.as_str())
215 }
216 }
217 }
218}
219
220#[cfg(feature = "parser")]
221pub fn parse_layout_flex_shrink<'a>(
222 input: &'a str,
223) -> Result<LayoutFlexShrink, FlexShrinkParseError<'a>> {
224 match parse_float_value(input) {
225 Ok(o) => {
226 if o.get() < 0.0 {
227 Err(FlexShrinkParseError::NegativeValue(input))
228 } else {
229 Ok(LayoutFlexShrink { inner: o })
230 }
231 }
232 Err(e) => Err(FlexShrinkParseError::ParseFloat(e, input)),
233 }
234}
235
236#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
242#[repr(C)]
243pub enum LayoutFlexDirection {
244 Row,
245 RowReverse,
246 Column,
247 ColumnReverse,
248}
249
250impl Default for LayoutFlexDirection {
251 fn default() -> Self {
252 Self::Row
253 }
254}
255
256#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
257#[repr(C)]
258pub enum LayoutAxis {
259 Horizontal,
260 Vertical,
261}
262
263impl LayoutFlexDirection {
264 pub fn get_axis(&self) -> LayoutAxis {
265 match self {
266 Self::Row | Self::RowReverse => LayoutAxis::Horizontal,
267 Self::Column | Self::ColumnReverse => LayoutAxis::Vertical,
268 }
269 }
270
271 pub fn is_reverse(&self) -> bool {
272 matches!(self, Self::RowReverse | Self::ColumnReverse)
273 }
274}
275
276impl PrintAsCssValue for LayoutFlexDirection {
277 fn print_as_css_value(&self) -> String {
278 String::from(match self {
279 Self::Row => "row",
280 Self::RowReverse => "row-reverse",
281 Self::Column => "column",
282 Self::ColumnReverse => "column-reverse",
283 })
284 }
285}
286impl crate::format_rust_code::FormatAsRustCode for LayoutFlexBasis {
288 fn format_as_rust_code(&self, _tabs: usize) -> String {
289 match self {
290 LayoutFlexBasis::Auto => String::from("LayoutFlexBasis::Auto"),
291 LayoutFlexBasis::Exact(px) => {
292 format!(
293 "LayoutFlexBasis::Exact({})",
294 crate::format_rust_code::format_pixel_value(px)
295 )
296 }
297 }
298 }
299}
300#[cfg(feature = "parser")]
301#[derive(Clone, PartialEq)]
302pub enum FlexDirectionParseError<'a> {
303 InvalidValue(&'a str),
304}
305
306#[cfg(feature = "parser")]
307impl_debug_as_display!(FlexDirectionParseError<'a>);
308#[cfg(feature = "parser")]
309impl_display! { FlexDirectionParseError<'a>, {
310 InvalidValue(s) => format!("Invalid flex-direction value: \"{}\"", s),
311}}
312
313#[cfg(feature = "parser")]
314#[derive(Debug, Clone, PartialEq)]
315pub enum FlexDirectionParseErrorOwned {
316 InvalidValue(String),
317}
318
319#[cfg(feature = "parser")]
320impl<'a> FlexDirectionParseError<'a> {
321 pub fn to_contained(&self) -> FlexDirectionParseErrorOwned {
322 match self {
323 Self::InvalidValue(s) => FlexDirectionParseErrorOwned::InvalidValue(s.to_string()),
324 }
325 }
326}
327
328#[cfg(feature = "parser")]
329impl FlexDirectionParseErrorOwned {
330 pub fn to_shared<'a>(&'a self) -> FlexDirectionParseError<'a> {
331 match self {
332 Self::InvalidValue(s) => FlexDirectionParseError::InvalidValue(s.as_str()),
333 }
334 }
335}
336
337#[cfg(feature = "parser")]
338pub fn parse_layout_flex_direction<'a>(
339 input: &'a str,
340) -> Result<LayoutFlexDirection, FlexDirectionParseError<'a>> {
341 match input.trim() {
342 "row" => Ok(LayoutFlexDirection::Row),
343 "row-reverse" => Ok(LayoutFlexDirection::RowReverse),
344 "column" => Ok(LayoutFlexDirection::Column),
345 "column-reverse" => Ok(LayoutFlexDirection::ColumnReverse),
346 _ => Err(FlexDirectionParseError::InvalidValue(input)),
347 }
348}
349
350#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
356#[repr(C)]
357pub enum LayoutFlexWrap {
358 Wrap,
359 NoWrap,
360 WrapReverse,
361}
362
363impl Default for LayoutFlexWrap {
364 fn default() -> Self {
365 Self::NoWrap
366 }
367}
368
369impl PrintAsCssValue for LayoutFlexWrap {
370 fn print_as_css_value(&self) -> String {
371 String::from(match self {
372 Self::Wrap => "wrap",
373 Self::NoWrap => "nowrap",
374 Self::WrapReverse => "wrap-reverse",
375 })
376 }
377}
378
379#[cfg(feature = "parser")]
380#[derive(Clone, PartialEq)]
381pub enum FlexWrapParseError<'a> {
382 InvalidValue(&'a str),
383}
384
385#[cfg(feature = "parser")]
386impl_debug_as_display!(FlexWrapParseError<'a>);
387#[cfg(feature = "parser")]
388impl_display! { FlexWrapParseError<'a>, {
389 InvalidValue(s) => format!("Invalid flex-wrap value: \"{}\"", s),
390}}
391
392#[cfg(feature = "parser")]
393#[derive(Debug, Clone, PartialEq)]
394pub enum FlexWrapParseErrorOwned {
395 InvalidValue(String),
396}
397
398#[cfg(feature = "parser")]
399impl<'a> FlexWrapParseError<'a> {
400 pub fn to_contained(&self) -> FlexWrapParseErrorOwned {
401 match self {
402 Self::InvalidValue(s) => FlexWrapParseErrorOwned::InvalidValue(s.to_string()),
403 }
404 }
405}
406
407#[cfg(feature = "parser")]
408impl FlexWrapParseErrorOwned {
409 pub fn to_shared<'a>(&'a self) -> FlexWrapParseError<'a> {
410 match self {
411 Self::InvalidValue(s) => FlexWrapParseError::InvalidValue(s.as_str()),
412 }
413 }
414}
415
416#[cfg(feature = "parser")]
417pub fn parse_layout_flex_wrap<'a>(
418 input: &'a str,
419) -> Result<LayoutFlexWrap, FlexWrapParseError<'a>> {
420 match input.trim() {
421 "wrap" => Ok(LayoutFlexWrap::Wrap),
422 "nowrap" => Ok(LayoutFlexWrap::NoWrap),
423 "wrap-reverse" => Ok(LayoutFlexWrap::WrapReverse),
424 _ => Err(FlexWrapParseError::InvalidValue(input)),
425 }
426}
427
428#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
434#[repr(C)]
435pub enum LayoutJustifyContent {
436 FlexStart,
437 FlexEnd,
438 Start,
439 End,
440 Center,
441 SpaceBetween,
442 SpaceAround,
443 SpaceEvenly,
444}
445
446impl Default for LayoutJustifyContent {
447 fn default() -> Self {
448 Self::Start
449 }
450}
451
452impl PrintAsCssValue for LayoutJustifyContent {
453 fn print_as_css_value(&self) -> String {
454 String::from(match self {
455 Self::Start => "start",
456 Self::End => "end",
457 Self::FlexStart => "flex-start",
458 Self::FlexEnd => "flex-end",
459 Self::Center => "center",
460 Self::SpaceBetween => "space-between",
461 Self::SpaceAround => "space-around",
462 Self::SpaceEvenly => "space-evenly",
463 })
464 }
465}
466
467#[cfg(feature = "parser")]
468#[derive(Clone, PartialEq)]
469pub enum JustifyContentParseError<'a> {
470 InvalidValue(&'a str),
471}
472
473#[cfg(feature = "parser")]
474impl_debug_as_display!(JustifyContentParseError<'a>);
475#[cfg(feature = "parser")]
476impl_display! { JustifyContentParseError<'a>, {
477 InvalidValue(s) => format!("Invalid justify-content value: \"{}\"", s),
478}}
479
480#[cfg(feature = "parser")]
481#[derive(Debug, Clone, PartialEq)]
482pub enum JustifyContentParseErrorOwned {
483 InvalidValue(String),
484}
485
486#[cfg(feature = "parser")]
487impl<'a> JustifyContentParseError<'a> {
488 pub fn to_contained(&self) -> JustifyContentParseErrorOwned {
489 match self {
490 Self::InvalidValue(s) => JustifyContentParseErrorOwned::InvalidValue(s.to_string()),
491 }
492 }
493}
494
495#[cfg(feature = "parser")]
496impl JustifyContentParseErrorOwned {
497 pub fn to_shared<'a>(&'a self) -> JustifyContentParseError<'a> {
498 match self {
499 Self::InvalidValue(s) => JustifyContentParseError::InvalidValue(s.as_str()),
500 }
501 }
502}
503
504#[cfg(feature = "parser")]
505pub fn parse_layout_justify_content<'a>(
506 input: &'a str,
507) -> Result<LayoutJustifyContent, JustifyContentParseError<'a>> {
508 match input.trim() {
509 "flex-start" => Ok(LayoutJustifyContent::Start),
510 "flex-end" => Ok(LayoutJustifyContent::End),
511 "center" => Ok(LayoutJustifyContent::Center),
512 "space-between" => Ok(LayoutJustifyContent::SpaceBetween),
513 "space-around" => Ok(LayoutJustifyContent::SpaceAround),
514 "space-evenly" => Ok(LayoutJustifyContent::SpaceEvenly),
515 _ => Err(JustifyContentParseError::InvalidValue(input)),
516 }
517}
518
519#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
525#[repr(C)]
526pub enum LayoutAlignItems {
527 Stretch,
528 Center,
529 Start,
530 End,
531 Baseline,
532}
533
534impl Default for LayoutAlignItems {
535 fn default() -> Self {
536 Self::Stretch
537 }
538}
539
540impl PrintAsCssValue for LayoutAlignItems {
541 fn print_as_css_value(&self) -> String {
542 String::from(match self {
543 Self::Stretch => "stretch",
544 Self::Center => "center",
545 Self::Start => "flex-start",
546 Self::End => "flex-end",
547 Self::Baseline => "baseline",
548 })
549 }
550}
551
552#[cfg(feature = "parser")]
553#[derive(Clone, PartialEq)]
554pub enum AlignItemsParseError<'a> {
555 InvalidValue(&'a str),
556}
557
558#[cfg(feature = "parser")]
559impl_debug_as_display!(AlignItemsParseError<'a>);
560#[cfg(feature = "parser")]
561impl_display! { AlignItemsParseError<'a>, {
562 InvalidValue(s) => format!("Invalid align-items value: \"{}\"", s),
563}}
564
565#[cfg(feature = "parser")]
566#[derive(Debug, Clone, PartialEq)]
567pub enum AlignItemsParseErrorOwned {
568 InvalidValue(String),
569}
570
571#[cfg(feature = "parser")]
572impl<'a> AlignItemsParseError<'a> {
573 pub fn to_contained(&self) -> AlignItemsParseErrorOwned {
574 match self {
575 Self::InvalidValue(s) => AlignItemsParseErrorOwned::InvalidValue(s.to_string()),
576 }
577 }
578}
579
580#[cfg(feature = "parser")]
581impl AlignItemsParseErrorOwned {
582 pub fn to_shared<'a>(&'a self) -> AlignItemsParseError<'a> {
583 match self {
584 Self::InvalidValue(s) => AlignItemsParseError::InvalidValue(s.as_str()),
585 }
586 }
587}
588
589#[cfg(feature = "parser")]
590pub fn parse_layout_align_items<'a>(
591 input: &'a str,
592) -> Result<LayoutAlignItems, AlignItemsParseError<'a>> {
593 match input.trim() {
594 "stretch" => Ok(LayoutAlignItems::Stretch),
595 "center" => Ok(LayoutAlignItems::Center),
596 "flex-start" => Ok(LayoutAlignItems::Start),
597 "flex-end" => Ok(LayoutAlignItems::End),
598 "baseline" => Ok(LayoutAlignItems::Baseline),
599 _ => Err(AlignItemsParseError::InvalidValue(input)),
600 }
601}
602
603#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
609#[repr(C)]
610pub enum LayoutAlignContent {
611 Stretch,
612 Center,
613 Start,
614 End,
615 SpaceBetween,
616 SpaceAround,
617}
618
619impl Default for LayoutAlignContent {
620 fn default() -> Self {
621 Self::Stretch
622 }
623}
624
625impl PrintAsCssValue for LayoutAlignContent {
626 fn print_as_css_value(&self) -> String {
627 String::from(match self {
628 Self::Stretch => "stretch",
629 Self::Center => "center",
630 Self::Start => "flex-start",
631 Self::End => "flex-end",
632 Self::SpaceBetween => "space-between",
633 Self::SpaceAround => "space-around",
634 })
635 }
636}
637
638#[cfg(feature = "parser")]
639#[derive(Clone, PartialEq)]
640pub enum AlignContentParseError<'a> {
641 InvalidValue(&'a str),
642}
643
644#[cfg(feature = "parser")]
645impl_debug_as_display!(AlignContentParseError<'a>);
646#[cfg(feature = "parser")]
647impl_display! { AlignContentParseError<'a>, {
648 InvalidValue(s) => format!("Invalid align-content value: \"{}\"", s),
649}}
650
651#[cfg(feature = "parser")]
652#[derive(Debug, Clone, PartialEq)]
653pub enum AlignContentParseErrorOwned {
654 InvalidValue(String),
655}
656
657#[cfg(feature = "parser")]
658impl<'a> AlignContentParseError<'a> {
659 pub fn to_contained(&self) -> AlignContentParseErrorOwned {
660 match self {
661 Self::InvalidValue(s) => AlignContentParseErrorOwned::InvalidValue(s.to_string()),
662 }
663 }
664}
665
666#[cfg(feature = "parser")]
667impl AlignContentParseErrorOwned {
668 pub fn to_shared<'a>(&'a self) -> AlignContentParseError<'a> {
669 match self {
670 Self::InvalidValue(s) => AlignContentParseError::InvalidValue(s.as_str()),
671 }
672 }
673}
674
675#[cfg(feature = "parser")]
676pub fn parse_layout_align_content<'a>(
677 input: &'a str,
678) -> Result<LayoutAlignContent, AlignContentParseError<'a>> {
679 match input.trim() {
680 "stretch" => Ok(LayoutAlignContent::Stretch),
681 "center" => Ok(LayoutAlignContent::Center),
682 "flex-start" => Ok(LayoutAlignContent::Start),
683 "flex-end" => Ok(LayoutAlignContent::End),
684 "space-between" => Ok(LayoutAlignContent::SpaceBetween),
685 "space-around" => Ok(LayoutAlignContent::SpaceAround),
686 _ => Err(AlignContentParseError::InvalidValue(input)),
687 }
688}
689
690#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
696#[repr(C)]
697pub enum LayoutAlignSelf {
698 Auto,
699 Stretch,
700 Center,
701 Start,
702 End,
703 Baseline,
704}
705
706impl Default for LayoutAlignSelf {
707 fn default() -> Self {
708 Self::Auto
709 }
710}
711
712impl PrintAsCssValue for LayoutAlignSelf {
713 fn print_as_css_value(&self) -> String {
714 String::from(match self {
715 Self::Auto => "auto",
716 Self::Stretch => "stretch",
717 Self::Center => "center",
718 Self::Start => "flex-start",
719 Self::End => "flex-end",
720 Self::Baseline => "baseline",
721 })
722 }
723}
724
725impl FormatAsRustCode for LayoutAlignSelf {
726 fn format_as_rust_code(&self, _tabs: usize) -> String {
727 format!(
728 "LayoutAlignSelf::{}",
729 match self {
730 LayoutAlignSelf::Auto => "Auto",
731 LayoutAlignSelf::Stretch => "Stretch",
732 LayoutAlignSelf::Center => "Center",
733 LayoutAlignSelf::Start => "Start",
734 LayoutAlignSelf::End => "End",
735 LayoutAlignSelf::Baseline => "Baseline",
736 }
737 )
738 }
739}
740
741#[cfg(feature = "parser")]
742#[derive(Clone, PartialEq)]
743pub enum AlignSelfParseError<'a> {
744 InvalidValue(&'a str),
745}
746
747#[cfg(feature = "parser")]
748impl_debug_as_display!(AlignSelfParseError<'a>);
749#[cfg(feature = "parser")]
750impl_display! { AlignSelfParseError<'a>, {
751 InvalidValue(s) => format!("Invalid align-self value: \"{}\"", s),
752}}
753
754#[cfg(feature = "parser")]
755#[derive(Debug, Clone, PartialEq)]
756pub enum AlignSelfParseErrorOwned {
757 InvalidValue(String),
758}
759
760#[cfg(feature = "parser")]
761impl<'a> AlignSelfParseError<'a> {
762 pub fn to_contained(&self) -> AlignSelfParseErrorOwned {
763 match self {
764 Self::InvalidValue(s) => AlignSelfParseErrorOwned::InvalidValue(s.to_string()),
765 }
766 }
767}
768
769#[cfg(feature = "parser")]
770impl AlignSelfParseErrorOwned {
771 pub fn to_shared<'a>(&'a self) -> AlignSelfParseError<'a> {
772 match self {
773 Self::InvalidValue(s) => AlignSelfParseError::InvalidValue(s.as_str()),
774 }
775 }
776}
777
778#[cfg(feature = "parser")]
779pub fn parse_layout_align_self<'a>(
780 input: &'a str,
781) -> Result<LayoutAlignSelf, AlignSelfParseError<'a>> {
782 match input.trim() {
783 "auto" => Ok(LayoutAlignSelf::Auto),
784 "stretch" => Ok(LayoutAlignSelf::Stretch),
785 "center" => Ok(LayoutAlignSelf::Center),
786 "flex-start" => Ok(LayoutAlignSelf::Start),
787 "flex-end" => Ok(LayoutAlignSelf::End),
788 "baseline" => Ok(LayoutAlignSelf::Baseline),
789 _ => Err(AlignSelfParseError::InvalidValue(input)),
790 }
791}
792
793#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
797#[repr(C, u8)]
798pub enum LayoutFlexBasis {
799 Auto,
801 Exact(crate::props::basic::pixel::PixelValue),
803}
804
805impl core::fmt::Debug for LayoutFlexBasis {
806 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
807 write!(f, "{}", self.print_as_css_value())
808 }
809}
810
811impl Default for LayoutFlexBasis {
812 fn default() -> Self {
813 LayoutFlexBasis::Auto
814 }
815}
816
817impl PrintAsCssValue for LayoutFlexBasis {
818 fn print_as_css_value(&self) -> String {
819 match self {
820 LayoutFlexBasis::Auto => "auto".to_string(),
821 LayoutFlexBasis::Exact(px) => px.print_as_css_value(),
822 }
823 }
824}
825
826#[cfg(feature = "parser")]
827#[derive(Clone, PartialEq)]
828pub enum FlexBasisParseError<'a> {
829 InvalidValue(&'a str),
830}
831
832#[cfg(feature = "parser")]
833impl_debug_as_display!(FlexBasisParseError<'a>);
834#[cfg(feature = "parser")]
835impl_display! { FlexBasisParseError<'a>, {
836 InvalidValue(e) => format!("Invalid flex-basis value: \"{}\"", e),
837}}
838
839#[cfg(feature = "parser")]
840#[derive(Debug, Clone, PartialEq)]
841pub enum FlexBasisParseErrorOwned {
842 InvalidValue(String),
843}
844
845#[cfg(feature = "parser")]
846impl<'a> FlexBasisParseError<'a> {
847 pub fn to_contained(&self) -> FlexBasisParseErrorOwned {
848 match self {
849 FlexBasisParseError::InvalidValue(s) => {
850 FlexBasisParseErrorOwned::InvalidValue(s.to_string())
851 }
852 }
853 }
854}
855
856#[cfg(feature = "parser")]
857impl FlexBasisParseErrorOwned {
858 pub fn to_shared<'a>(&'a self) -> FlexBasisParseError<'a> {
859 match self {
860 FlexBasisParseErrorOwned::InvalidValue(s) => {
861 FlexBasisParseError::InvalidValue(s.as_str())
862 }
863 }
864 }
865}
866
867#[cfg(feature = "parser")]
868pub fn parse_layout_flex_basis<'a>(
869 input: &'a str,
870) -> Result<LayoutFlexBasis, FlexBasisParseError<'a>> {
871 use crate::props::basic::pixel::parse_pixel_value;
872
873 match input.trim() {
874 "auto" => Ok(LayoutFlexBasis::Auto),
875 s => parse_pixel_value(s)
876 .map(LayoutFlexBasis::Exact)
877 .map_err(|_| FlexBasisParseError::InvalidValue(input)),
878 }
879}
880
881#[cfg(all(test, feature = "parser"))]
882mod tests {
883 use super::*;
884 use crate::props::basic::pixel::PixelValue;
885
886 #[test]
887 fn test_parse_layout_flex_grow() {
888 assert_eq!(parse_layout_flex_grow("0").unwrap().inner.get(), 0.0);
889 assert_eq!(parse_layout_flex_grow("1").unwrap().inner.get(), 1.0);
890 assert_eq!(parse_layout_flex_grow("2.5").unwrap().inner.get(), 2.5);
891 assert_eq!(parse_layout_flex_grow(" 0.5 ").unwrap().inner.get(), 0.5);
892 assert!(parse_layout_flex_grow("none").is_err());
893 assert!(parse_layout_flex_grow("-1").is_err()); }
895
896 #[test]
897 fn test_parse_layout_flex_shrink() {
898 assert_eq!(parse_layout_flex_shrink("0").unwrap().inner.get(), 0.0);
899 assert_eq!(parse_layout_flex_shrink("1").unwrap().inner.get(), 1.0);
900 assert_eq!(parse_layout_flex_shrink("3.0").unwrap().inner.get(), 3.0);
901 assert_eq!(parse_layout_flex_shrink(" 0.2 ").unwrap().inner.get(), 0.2);
902 assert!(parse_layout_flex_shrink("auto").is_err());
903 assert!(parse_layout_flex_shrink("-1").is_err()); }
905
906 #[test]
907 fn test_parse_layout_flex_direction() {
908 assert_eq!(
909 parse_layout_flex_direction("row").unwrap(),
910 LayoutFlexDirection::Row
911 );
912 assert_eq!(
913 parse_layout_flex_direction("row-reverse").unwrap(),
914 LayoutFlexDirection::RowReverse
915 );
916 assert_eq!(
917 parse_layout_flex_direction("column").unwrap(),
918 LayoutFlexDirection::Column
919 );
920 assert_eq!(
921 parse_layout_flex_direction("column-reverse").unwrap(),
922 LayoutFlexDirection::ColumnReverse
923 );
924 assert_eq!(
925 parse_layout_flex_direction(" row ").unwrap(),
926 LayoutFlexDirection::Row
927 );
928 assert!(parse_layout_flex_direction("reversed-row").is_err());
929 }
930
931 #[test]
932 fn test_parse_layout_flex_wrap() {
933 assert_eq!(
934 parse_layout_flex_wrap("nowrap").unwrap(),
935 LayoutFlexWrap::NoWrap
936 );
937 assert_eq!(
938 parse_layout_flex_wrap("wrap").unwrap(),
939 LayoutFlexWrap::Wrap
940 );
941 assert_eq!(
942 parse_layout_flex_wrap("wrap-reverse").unwrap(),
943 LayoutFlexWrap::WrapReverse
944 );
945 assert_eq!(
946 parse_layout_flex_wrap(" wrap ").unwrap(),
947 LayoutFlexWrap::Wrap
948 );
949 assert!(parse_layout_flex_wrap("wrap reverse").is_err());
950 }
951
952 #[test]
953 fn test_parse_layout_justify_content() {
954 assert_eq!(
955 parse_layout_justify_content("flex-start").unwrap(),
956 LayoutJustifyContent::Start
957 );
958 assert_eq!(
959 parse_layout_justify_content("flex-end").unwrap(),
960 LayoutJustifyContent::End
961 );
962 assert_eq!(
963 parse_layout_justify_content("center").unwrap(),
964 LayoutJustifyContent::Center
965 );
966 assert_eq!(
967 parse_layout_justify_content("space-between").unwrap(),
968 LayoutJustifyContent::SpaceBetween
969 );
970 assert_eq!(
971 parse_layout_justify_content("space-around").unwrap(),
972 LayoutJustifyContent::SpaceAround
973 );
974 assert_eq!(
975 parse_layout_justify_content("space-evenly").unwrap(),
976 LayoutJustifyContent::SpaceEvenly
977 );
978 assert_eq!(
979 parse_layout_justify_content(" center ").unwrap(),
980 LayoutJustifyContent::Center
981 );
982 assert!(parse_layout_justify_content("start").is_err());
983 }
984
985 #[test]
986 fn test_parse_layout_align_items() {
987 assert_eq!(
988 parse_layout_align_items("stretch").unwrap(),
989 LayoutAlignItems::Stretch
990 );
991 assert_eq!(
992 parse_layout_align_items("flex-start").unwrap(),
993 LayoutAlignItems::Start
994 );
995 assert_eq!(
996 parse_layout_align_items("flex-end").unwrap(),
997 LayoutAlignItems::End
998 );
999 assert_eq!(
1000 parse_layout_align_items("center").unwrap(),
1001 LayoutAlignItems::Center
1002 );
1003 assert_eq!(
1004 parse_layout_align_items("baseline").unwrap(),
1005 LayoutAlignItems::Baseline
1006 );
1007 assert!(parse_layout_align_items("end").is_err());
1008 }
1009
1010 #[test]
1011 fn test_parse_layout_align_content() {
1012 assert_eq!(
1013 parse_layout_align_content("stretch").unwrap(),
1014 LayoutAlignContent::Stretch
1015 );
1016 assert_eq!(
1017 parse_layout_align_content("flex-start").unwrap(),
1018 LayoutAlignContent::Start
1019 );
1020 assert_eq!(
1021 parse_layout_align_content("flex-end").unwrap(),
1022 LayoutAlignContent::End
1023 );
1024 assert_eq!(
1025 parse_layout_align_content("center").unwrap(),
1026 LayoutAlignContent::Center
1027 );
1028 assert_eq!(
1029 parse_layout_align_content("space-between").unwrap(),
1030 LayoutAlignContent::SpaceBetween
1031 );
1032 assert_eq!(
1033 parse_layout_align_content("space-around").unwrap(),
1034 LayoutAlignContent::SpaceAround
1035 );
1036 assert!(parse_layout_align_content("space-evenly").is_err()); }
1038
1039 #[test]
1040 fn test_parse_layout_flex_basis() {
1041 assert_eq!(
1042 parse_layout_flex_basis("auto").unwrap(),
1043 LayoutFlexBasis::Auto
1044 );
1045 assert_eq!(
1046 parse_layout_flex_basis("200px").unwrap(),
1047 LayoutFlexBasis::Exact(PixelValue::px(200.0))
1048 );
1049 assert_eq!(
1050 parse_layout_flex_basis("50%").unwrap(),
1051 LayoutFlexBasis::Exact(PixelValue::percent(50.0))
1052 );
1053 assert_eq!(
1054 parse_layout_flex_basis(" 10em ").unwrap(),
1055 LayoutFlexBasis::Exact(PixelValue::em(10.0))
1056 );
1057 assert!(parse_layout_flex_basis("none").is_err());
1058 assert_eq!(
1060 parse_layout_flex_basis("200").unwrap(),
1061 LayoutFlexBasis::Exact(PixelValue::px(200.0))
1062 );
1063 assert_eq!(
1064 parse_layout_flex_basis("0").unwrap(),
1065 LayoutFlexBasis::Exact(PixelValue::px(0.0))
1066 );
1067 }
1068}