1use crate::classes::ClassBuilder;
7use serde::{Deserialize, Serialize};
8use std::fmt;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12pub enum MaskType {
13 None,
15 Alpha,
17 Luminance,
19}
20
21impl fmt::Display for MaskType {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 match self {
24 MaskType::None => write!(f, "none"),
25 MaskType::Alpha => write!(f, "alpha"),
26 MaskType::Luminance => write!(f, "luminance"),
27 }
28 }
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
33pub enum MaskMode {
34 Alpha,
36 Luminance,
38 MatchSource,
40}
41
42impl fmt::Display for MaskMode {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 match self {
45 MaskMode::Alpha => write!(f, "alpha"),
46 MaskMode::Luminance => write!(f, "luminance"),
47 MaskMode::MatchSource => write!(f, "match-source"),
48 }
49 }
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
54pub enum MaskComposite {
55 Add,
57 Subtract,
59 Intersect,
61 Exclude,
63}
64
65impl fmt::Display for MaskComposite {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 match self {
68 MaskComposite::Add => write!(f, "add"),
69 MaskComposite::Subtract => write!(f, "subtract"),
70 MaskComposite::Intersect => write!(f, "intersect"),
71 MaskComposite::Exclude => write!(f, "exclude"),
72 }
73 }
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
78pub enum MaskRepeat {
79 NoRepeat,
81 Repeat,
83 RepeatX,
85 RepeatY,
87 Round,
89 Space,
91}
92
93impl fmt::Display for MaskRepeat {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 match self {
96 MaskRepeat::NoRepeat => write!(f, "no-repeat"),
97 MaskRepeat::Repeat => write!(f, "repeat"),
98 MaskRepeat::RepeatX => write!(f, "repeat-x"),
99 MaskRepeat::RepeatY => write!(f, "repeat-y"),
100 MaskRepeat::Round => write!(f, "round"),
101 MaskRepeat::Space => write!(f, "space"),
102 }
103 }
104}
105
106#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
108pub enum MaskSize {
109 Auto,
111 Cover,
113 Contain,
115}
116
117impl fmt::Display for MaskSize {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 match self {
120 MaskSize::Auto => write!(f, "auto"),
121 MaskSize::Cover => write!(f, "cover"),
122 MaskSize::Contain => write!(f, "contain"),
123 }
124 }
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
129pub enum MaskPosition {
130 Center,
132 Top,
134 Bottom,
136 Left,
138 Right,
140 TopLeft,
142 TopRight,
144 BottomLeft,
146 BottomRight,
148}
149
150impl fmt::Display for MaskPosition {
151 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152 match self {
153 MaskPosition::Center => write!(f, "center"),
154 MaskPosition::Top => write!(f, "top"),
155 MaskPosition::Bottom => write!(f, "bottom"),
156 MaskPosition::Left => write!(f, "left"),
157 MaskPosition::Right => write!(f, "right"),
158 MaskPosition::TopLeft => write!(f, "top left"),
159 MaskPosition::TopRight => write!(f, "top right"),
160 MaskPosition::BottomLeft => write!(f, "bottom left"),
161 MaskPosition::BottomRight => write!(f, "bottom right"),
162 }
163 }
164}
165
166#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
168pub enum MaskClip {
169 BorderBox,
171 PaddingBox,
173 ContentBox,
175 Text,
177}
178
179impl fmt::Display for MaskClip {
180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 match self {
182 MaskClip::BorderBox => write!(f, "border-box"),
183 MaskClip::PaddingBox => write!(f, "padding-box"),
184 MaskClip::ContentBox => write!(f, "content-box"),
185 MaskClip::Text => write!(f, "text"),
186 }
187 }
188}
189
190#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
192pub enum MaskOrigin {
193 BorderBox,
195 PaddingBox,
197 ContentBox,
199}
200
201impl fmt::Display for MaskOrigin {
202 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203 match self {
204 MaskOrigin::BorderBox => write!(f, "border-box"),
205 MaskOrigin::PaddingBox => write!(f, "padding-box"),
206 MaskOrigin::ContentBox => write!(f, "content-box"),
207 }
208 }
209}
210
211pub trait MaskUtilities {
213 fn mask_none(self) -> Self;
215 fn mask_alpha(self) -> Self;
217 fn mask_luminance(self) -> Self;
219 fn mask_repeat_none(self) -> Self;
221 fn mask_repeat(self) -> Self;
223 fn mask_repeat_x(self) -> Self;
225 fn mask_repeat_y(self) -> Self;
227 fn mask_repeat_round(self) -> Self;
229 fn mask_repeat_space(self) -> Self;
231 fn mask_size_auto(self) -> Self;
233 fn mask_size_cover(self) -> Self;
235 fn mask_size_contain(self) -> Self;
237 fn mask_center(self) -> Self;
239 fn mask_top(self) -> Self;
241 fn mask_bottom(self) -> Self;
243 fn mask_left(self) -> Self;
245 fn mask_right(self) -> Self;
247 fn mask_top_left(self) -> Self;
249 fn mask_top_right(self) -> Self;
251 fn mask_bottom_left(self) -> Self;
253 fn mask_bottom_right(self) -> Self;
255 fn mask_clip_border(self) -> Self;
257 fn mask_clip_padding(self) -> Self;
259 fn mask_clip_content(self) -> Self;
261 fn mask_clip_text(self) -> Self;
263 fn mask_origin_border(self) -> Self;
265 fn mask_origin_padding(self) -> Self;
267 fn mask_origin_content(self) -> Self;
269}
270
271impl MaskUtilities for ClassBuilder {
272 fn mask_none(self) -> Self {
273 self.class("mask-none")
274 }
275
276 fn mask_alpha(self) -> Self {
277 self.class("mask-alpha")
278 }
279
280 fn mask_luminance(self) -> Self {
281 self.class("mask-luminance")
282 }
283
284 fn mask_repeat_none(self) -> Self {
285 self.class("mask-repeat-none")
286 }
287
288 fn mask_repeat(self) -> Self {
289 self.class("mask-repeat")
290 }
291
292 fn mask_repeat_x(self) -> Self {
293 self.class("mask-repeat-x")
294 }
295
296 fn mask_repeat_y(self) -> Self {
297 self.class("mask-repeat-y")
298 }
299
300 fn mask_repeat_round(self) -> Self {
301 self.class("mask-repeat-round")
302 }
303
304 fn mask_repeat_space(self) -> Self {
305 self.class("mask-repeat-space")
306 }
307
308 fn mask_size_auto(self) -> Self {
309 self.class("mask-size-auto")
310 }
311
312 fn mask_size_cover(self) -> Self {
313 self.class("mask-size-cover")
314 }
315
316 fn mask_size_contain(self) -> Self {
317 self.class("mask-size-contain")
318 }
319
320 fn mask_center(self) -> Self {
321 self.class("mask-center")
322 }
323
324 fn mask_top(self) -> Self {
325 self.class("mask-top")
326 }
327
328 fn mask_bottom(self) -> Self {
329 self.class("mask-bottom")
330 }
331
332 fn mask_left(self) -> Self {
333 self.class("mask-left")
334 }
335
336 fn mask_right(self) -> Self {
337 self.class("mask-right")
338 }
339
340 fn mask_top_left(self) -> Self {
341 self.class("mask-top-left")
342 }
343
344 fn mask_top_right(self) -> Self {
345 self.class("mask-top-right")
346 }
347
348 fn mask_bottom_left(self) -> Self {
349 self.class("mask-bottom-left")
350 }
351
352 fn mask_bottom_right(self) -> Self {
353 self.class("mask-bottom-right")
354 }
355
356 fn mask_clip_border(self) -> Self {
357 self.class("mask-clip-border")
358 }
359
360 fn mask_clip_padding(self) -> Self {
361 self.class("mask-clip-padding")
362 }
363
364 fn mask_clip_content(self) -> Self {
365 self.class("mask-clip-content")
366 }
367
368 fn mask_clip_text(self) -> Self {
369 self.class("mask-clip-text")
370 }
371
372 fn mask_origin_border(self) -> Self {
373 self.class("mask-origin-border")
374 }
375
376 fn mask_origin_padding(self) -> Self {
377 self.class("mask-origin-padding")
378 }
379
380 fn mask_origin_content(self) -> Self {
381 self.class("mask-origin-content")
382 }
383}
384
385#[cfg(test)]
386mod tests {
387 use super::*;
388 use crate::classes::ClassBuilder;
389
390 #[test]
391 fn test_mask_type_enum_values() {
392 assert_eq!(MaskType::None.to_string(), "none");
393 assert_eq!(MaskType::Alpha.to_string(), "alpha");
394 assert_eq!(MaskType::Luminance.to_string(), "luminance");
395 }
396
397 #[test]
398 fn test_mask_mode_enum_values() {
399 assert_eq!(MaskMode::Alpha.to_string(), "alpha");
400 assert_eq!(MaskMode::Luminance.to_string(), "luminance");
401 assert_eq!(MaskMode::MatchSource.to_string(), "match-source");
402 }
403
404 #[test]
405 fn test_mask_composite_enum_values() {
406 assert_eq!(MaskComposite::Add.to_string(), "add");
407 assert_eq!(MaskComposite::Subtract.to_string(), "subtract");
408 assert_eq!(MaskComposite::Intersect.to_string(), "intersect");
409 assert_eq!(MaskComposite::Exclude.to_string(), "exclude");
410 }
411
412 #[test]
413 fn test_mask_repeat_enum_values() {
414 assert_eq!(MaskRepeat::NoRepeat.to_string(), "no-repeat");
415 assert_eq!(MaskRepeat::Repeat.to_string(), "repeat");
416 assert_eq!(MaskRepeat::RepeatX.to_string(), "repeat-x");
417 assert_eq!(MaskRepeat::RepeatY.to_string(), "repeat-y");
418 assert_eq!(MaskRepeat::Round.to_string(), "round");
419 assert_eq!(MaskRepeat::Space.to_string(), "space");
420 }
421
422 #[test]
423 fn test_mask_size_enum_values() {
424 assert_eq!(MaskSize::Auto.to_string(), "auto");
425 assert_eq!(MaskSize::Cover.to_string(), "cover");
426 assert_eq!(MaskSize::Contain.to_string(), "contain");
427 }
428
429 #[test]
430 fn test_mask_position_enum_values() {
431 assert_eq!(MaskPosition::Center.to_string(), "center");
432 assert_eq!(MaskPosition::Top.to_string(), "top");
433 assert_eq!(MaskPosition::Bottom.to_string(), "bottom");
434 assert_eq!(MaskPosition::Left.to_string(), "left");
435 assert_eq!(MaskPosition::Right.to_string(), "right");
436 assert_eq!(MaskPosition::TopLeft.to_string(), "top left");
437 assert_eq!(MaskPosition::TopRight.to_string(), "top right");
438 assert_eq!(MaskPosition::BottomLeft.to_string(), "bottom left");
439 assert_eq!(MaskPosition::BottomRight.to_string(), "bottom right");
440 }
441
442 #[test]
443 fn test_mask_clip_enum_values() {
444 assert_eq!(MaskClip::BorderBox.to_string(), "border-box");
445 assert_eq!(MaskClip::PaddingBox.to_string(), "padding-box");
446 assert_eq!(MaskClip::ContentBox.to_string(), "content-box");
447 assert_eq!(MaskClip::Text.to_string(), "text");
448 }
449
450 #[test]
451 fn test_mask_origin_enum_values() {
452 assert_eq!(MaskOrigin::BorderBox.to_string(), "border-box");
453 assert_eq!(MaskOrigin::PaddingBox.to_string(), "padding-box");
454 assert_eq!(MaskOrigin::ContentBox.to_string(), "content-box");
455 }
456
457 #[test]
458 fn test_mask_utilities() {
459 let classes = ClassBuilder::new()
460 .mask_alpha()
461 .mask_repeat_round()
462 .mask_size_cover()
463 .mask_center()
464 .mask_clip_border()
465 .mask_origin_padding();
466
467 let result = classes.build();
468 assert!(result.classes.contains("mask-alpha"));
469 assert!(result.classes.contains("mask-repeat-round"));
470 assert!(result.classes.contains("mask-size-cover"));
471 assert!(result.classes.contains("mask-center"));
472 assert!(result.classes.contains("mask-clip-border"));
473 assert!(result.classes.contains("mask-origin-padding"));
474 }
475
476 #[test]
477 fn test_mask_serialization() {
478 let mask_type = MaskType::Alpha;
479 let serialized = serde_json::to_string(&mask_type).unwrap();
480 let deserialized: MaskType = serde_json::from_str(&serialized).unwrap();
481 assert_eq!(mask_type, deserialized);
482 }
483
484 #[test]
485 fn test_mask_comprehensive_usage() {
486 let classes = ClassBuilder::new()
487 .mask_luminance()
488 .mask_repeat_round()
489 .mask_size_contain()
490 .mask_top_left();
491
492 let result = classes.build();
493 assert!(result.classes.contains("mask-luminance"));
494 assert!(result.classes.contains("mask-repeat-round"));
495 assert!(result.classes.contains("mask-size-contain"));
496 assert!(result.classes.contains("mask-top-left"));
497 }
498}