azul_css/props/layout/
flow.rs1use alloc::string::{String, ToString};
4
5use crate::{corety::AzString, props::formatter::PrintAsCssValue};
6
7#[allow(variant_size_differences)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
11#[repr(C, u8)]
12#[derive(Default)]
13pub enum FlowInto {
14 #[default]
16 None,
17 Named(AzString),
19}
20
21
22impl PrintAsCssValue for FlowInto {
23 fn print_as_css_value(&self) -> String {
24 match self {
25 Self::None => "none".to_string(),
26 Self::Named(s) => s.to_string(),
27 }
28 }
29}
30
31#[allow(variant_size_differences)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
35#[repr(C, u8)]
36#[derive(Default)]
37pub enum FlowFrom {
38 #[default]
40 None,
41 Named(AzString),
43}
44
45
46impl PrintAsCssValue for FlowFrom {
47 fn print_as_css_value(&self) -> String {
48 match self {
49 Self::None => "none".to_string(),
50 Self::Named(s) => s.to_string(),
51 }
52 }
53}
54
55impl crate::codegen::format::FormatAsRustCode for FlowInto {
57 fn format_as_rust_code(&self, _tabs: usize) -> String {
58 match self {
59 Self::None => String::from("FlowInto::None"),
60 Self::Named(s) => format!(
61 "FlowInto::Named(AzString::from_const_str({:?}))",
62 s.as_str()
63 ),
64 }
65 }
66}
67
68impl crate::codegen::format::FormatAsRustCode for FlowFrom {
69 fn format_as_rust_code(&self, _tabs: usize) -> String {
70 match self {
71 Self::None => String::from("FlowFrom::None"),
72 Self::Named(s) => format!(
73 "FlowFrom::Named(AzString::from_const_str({:?}))",
74 s.as_str()
75 ),
76 }
77 }
78}
79
80#[cfg(feature = "parser")]
83pub mod parser {
84 #[allow(clippy::wildcard_imports)] use super::*;
86 use crate::corety::AzString;
87
88 macro_rules! define_flow_parser {
89 (
90 $fn_name:ident,
91 $struct_name:ident,
92 $error_name:ident,
93 $error_owned_name:ident,
94 $prop_name:expr
95 ) => {
96 #[derive(Clone, PartialEq, Eq)]
97 pub enum $error_name<'a> {
98 InvalidValue(&'a str),
99 }
100
101 impl_debug_as_display!($error_name<'a>);
102 impl_display! { $error_name<'a>, {
103 InvalidValue(v) => format!("Invalid {} value: \"{}\"", $prop_name, v),
104 }}
105
106 #[derive(Debug, Clone, PartialEq, Eq)]
107 #[repr(C, u8)]
108 pub enum $error_owned_name {
109 InvalidValue(AzString),
110 }
111
112 impl $error_name<'_> {
113 #[must_use] pub fn to_contained(&self) -> $error_owned_name {
114 match self {
115 Self::InvalidValue(s) => $error_owned_name::InvalidValue(s.to_string().into()),
116 }
117 }
118 }
119
120 impl $error_owned_name {
121 #[must_use] pub fn to_shared(&self) -> $error_name<'_> {
122 match self {
123 Self::InvalidValue(s) => $error_name::InvalidValue(s.as_str()),
124 }
125 }
126 }
127
128 pub fn $fn_name(input: &str) -> Result<$struct_name, $error_name<'_>> {
132 let trimmed = input.trim();
133 if trimmed.is_empty() {
134 return Err($error_name::InvalidValue(input));
135 }
136 match trimmed {
137 "none" => Ok($struct_name::None),
138 ident => Ok($struct_name::Named(ident.to_string().into())),
140 }
141 }
142 };
143 }
144
145 define_flow_parser!(
146 parse_flow_into,
147 FlowInto,
148 FlowIntoParseError,
149 FlowIntoParseErrorOwned,
150 "flow-into"
151 );
152 define_flow_parser!(
153 parse_flow_from,
154 FlowFrom,
155 FlowFromParseError,
156 FlowFromParseErrorOwned,
157 "flow-from"
158 );
159}
160
161#[cfg(feature = "parser")]
162pub use parser::*;
163
164#[cfg(all(test, feature = "parser"))]
165mod tests {
166 use super::*;
167
168 #[test]
169 fn test_parse_flow_into() {
170 assert_eq!(parse_flow_into("none").unwrap(), FlowInto::None);
171 assert_eq!(
172 parse_flow_into("my-article-flow").unwrap(),
173 FlowInto::Named("my-article-flow".into())
174 );
175 assert!(parse_flow_into("").is_err());
176 }
177
178 #[test]
179 fn test_parse_flow_from() {
180 assert_eq!(parse_flow_from("none").unwrap(), FlowFrom::None);
181 assert_eq!(
182 parse_flow_from(" main-thread ").unwrap(),
183 FlowFrom::Named("main-thread".into())
184 );
185 assert!(parse_flow_from("").is_err());
186 }
187}