azul_css/props/layout/
overflow.rs1use alloc::string::{String, ToString};
4
5use crate::props::formatter::PrintAsCssValue;
6
7#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
11#[repr(C)]
12pub enum LayoutOverflow {
13 Scroll,
15 Auto,
17 Hidden,
19 #[default]
21 Visible,
22 Clip,
24}
25
26impl LayoutOverflow {
27 pub fn needs_scrollbar(&self, currently_overflowing: bool) -> bool {
33 match self {
34 LayoutOverflow::Scroll => true,
35 LayoutOverflow::Auto => currently_overflowing,
36 LayoutOverflow::Hidden | LayoutOverflow::Visible | LayoutOverflow::Clip => false,
37 }
38 }
39
40 pub fn is_clipped(&self) -> bool {
41 matches!(
43 self,
44 LayoutOverflow::Hidden
45 | LayoutOverflow::Clip
46 | LayoutOverflow::Auto
47 | LayoutOverflow::Scroll
48 )
49 }
50
51 pub fn is_scroll(&self) -> bool {
52 matches!(self, LayoutOverflow::Scroll)
53 }
54
55 pub fn is_overflow_visible(&self) -> bool {
58 *self == LayoutOverflow::Visible
59 }
60
61 pub fn is_overflow_hidden(&self) -> bool {
63 *self == LayoutOverflow::Hidden
64 }
65}
66
67impl PrintAsCssValue for LayoutOverflow {
68 fn print_as_css_value(&self) -> String {
69 String::from(match self {
70 LayoutOverflow::Scroll => "scroll",
71 LayoutOverflow::Auto => "auto",
72 LayoutOverflow::Hidden => "hidden",
73 LayoutOverflow::Visible => "visible",
74 LayoutOverflow::Clip => "clip",
75 })
76 }
77}
78
79#[derive(Clone, PartialEq, Eq)]
83pub enum LayoutOverflowParseError<'a> {
84 InvalidValue(&'a str),
86}
87
88impl_debug_as_display!(LayoutOverflowParseError<'a>);
89impl_display! { LayoutOverflowParseError<'a>, {
90 InvalidValue(val) => format!(
91 "Invalid overflow value: \"{}\". Expected 'scroll', 'auto', 'hidden', 'visible', or 'clip'.", val
92 ),
93}}
94
95#[derive(Debug, Clone, PartialEq, Eq)]
97pub enum LayoutOverflowParseErrorOwned {
98 InvalidValue(String),
99}
100
101impl<'a> LayoutOverflowParseError<'a> {
102 pub fn to_contained(&self) -> LayoutOverflowParseErrorOwned {
104 match self {
105 LayoutOverflowParseError::InvalidValue(s) => {
106 LayoutOverflowParseErrorOwned::InvalidValue(s.to_string())
107 }
108 }
109 }
110}
111
112impl LayoutOverflowParseErrorOwned {
113 pub fn to_shared<'a>(&'a self) -> LayoutOverflowParseError<'a> {
115 match self {
116 LayoutOverflowParseErrorOwned::InvalidValue(s) => {
117 LayoutOverflowParseError::InvalidValue(s.as_str())
118 }
119 }
120 }
121}
122
123#[cfg(feature = "parser")]
124pub fn parse_layout_overflow<'a>(
126 input: &'a str,
127) -> Result<LayoutOverflow, LayoutOverflowParseError<'a>> {
128 let input_trimmed = input.trim();
129 match input_trimmed {
130 "scroll" => Ok(LayoutOverflow::Scroll),
131 "auto" => Ok(LayoutOverflow::Auto),
132 "hidden" => Ok(LayoutOverflow::Hidden),
133 "visible" => Ok(LayoutOverflow::Visible),
134 "clip" => Ok(LayoutOverflow::Clip),
135 _ => Err(LayoutOverflowParseError::InvalidValue(input)),
136 }
137}
138
139#[cfg(all(test, feature = "parser"))]
140mod tests {
141 use super::*;
142
143 #[test]
144 fn test_parse_layout_overflow_valid() {
145 assert_eq!(
146 parse_layout_overflow("visible").unwrap(),
147 LayoutOverflow::Visible
148 );
149 assert_eq!(
150 parse_layout_overflow("hidden").unwrap(),
151 LayoutOverflow::Hidden
152 );
153 assert_eq!(parse_layout_overflow("clip").unwrap(), LayoutOverflow::Clip);
154 assert_eq!(
155 parse_layout_overflow("scroll").unwrap(),
156 LayoutOverflow::Scroll
157 );
158 assert_eq!(parse_layout_overflow("auto").unwrap(), LayoutOverflow::Auto);
159 }
160
161 #[test]
162 fn test_parse_layout_overflow_whitespace() {
163 assert_eq!(
164 parse_layout_overflow(" scroll ").unwrap(),
165 LayoutOverflow::Scroll
166 );
167 }
168
169 #[test]
170 fn test_parse_layout_overflow_invalid() {
171 assert!(parse_layout_overflow("none").is_err());
172 assert!(parse_layout_overflow("").is_err());
173 assert!(parse_layout_overflow("auto scroll").is_err());
174 assert!(parse_layout_overflow("hidden-x").is_err());
175 }
176
177 #[test]
178 fn test_needs_scrollbar() {
179 assert!(LayoutOverflow::Scroll.needs_scrollbar(false));
180 assert!(LayoutOverflow::Scroll.needs_scrollbar(true));
181 assert!(LayoutOverflow::Auto.needs_scrollbar(true));
182 assert!(!LayoutOverflow::Auto.needs_scrollbar(false));
183 assert!(!LayoutOverflow::Hidden.needs_scrollbar(true));
184 assert!(!LayoutOverflow::Visible.needs_scrollbar(true));
185 assert!(!LayoutOverflow::Clip.needs_scrollbar(true));
186 }
187}