azul_css/props/layout/
flow.rs1use alloc::string::{String, ToString};
4
5use crate::{corety::AzString, props::formatter::PrintAsCssValue};
6
7#[allow(variant_size_differences)]
9#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[repr(C, u8)]
13#[derive(Default)]
14pub enum FlowInto {
15 #[default]
17 None,
18 Named(AzString),
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)]
33#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
36#[repr(C, u8)]
37#[derive(Default)]
38pub enum FlowFrom {
39 #[default]
41 None,
42 Named(AzString),
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)]
85 use super::*;
87 use crate::corety::AzString;
88
89 macro_rules! define_flow_parser {
90 (
91 $fn_name:ident,
92 $struct_name:ident,
93 $error_name:ident,
94 $error_owned_name:ident,
95 $prop_name:expr
96 ) => {
97 #[derive(Clone, PartialEq, Eq)]
98 pub enum $error_name<'a> {
99 InvalidValue(&'a str),
100 }
101
102 impl_debug_as_display!($error_name<'a>);
103 impl_display! { $error_name<'a>, {
104 InvalidValue(v) => format!("Invalid {} value: \"{}\"", $prop_name, v),
105 }}
106
107 #[derive(Debug, Clone, PartialEq, Eq)]
108 #[repr(C, u8)]
109 pub enum $error_owned_name {
110 InvalidValue(AzString),
111 }
112
113 impl $error_name<'_> {
114 #[must_use]
115 pub fn to_contained(&self) -> $error_owned_name {
116 match self {
117 Self::InvalidValue(s) => {
118 $error_owned_name::InvalidValue(s.to_string().into())
119 }
120 }
121 }
122 }
123
124 impl $error_owned_name {
125 #[must_use]
126 pub fn to_shared(&self) -> $error_name<'_> {
127 match self {
128 Self::InvalidValue(s) => $error_name::InvalidValue(s.as_str()),
129 }
130 }
131 }
132
133 pub fn $fn_name(input: &str) -> Result<$struct_name, $error_name<'_>> {
137 let trimmed = input.trim();
138 if trimmed.is_empty() {
139 return Err($error_name::InvalidValue(input));
140 }
141 match trimmed {
142 "none" => Ok($struct_name::None),
143 ident => Ok($struct_name::Named(ident.to_string().into())),
145 }
146 }
147 };
148 }
149
150 define_flow_parser!(
151 parse_flow_into,
152 FlowInto,
153 FlowIntoParseError,
154 FlowIntoParseErrorOwned,
155 "flow-into"
156 );
157 define_flow_parser!(
158 parse_flow_from,
159 FlowFrom,
160 FlowFromParseError,
161 FlowFromParseErrorOwned,
162 "flow-from"
163 );
164}
165
166#[cfg(feature = "parser")]
167pub use parser::*;
168
169#[cfg(all(test, feature = "parser"))]
170mod tests {
171 use super::*;
172
173 #[test]
174 fn test_parse_flow_into() {
175 assert_eq!(parse_flow_into("none").unwrap(), FlowInto::None);
176 assert_eq!(
177 parse_flow_into("my-article-flow").unwrap(),
178 FlowInto::Named("my-article-flow".into())
179 );
180 assert!(parse_flow_into("").is_err());
181 }
182
183 #[test]
184 fn test_parse_flow_from() {
185 assert_eq!(parse_flow_from("none").unwrap(), FlowFrom::None);
186 assert_eq!(
187 parse_flow_from(" main-thread ").unwrap(),
188 FlowFrom::Named("main-thread".into())
189 );
190 assert!(parse_flow_from("").is_err());
191 }
192}