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