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