1use super::prelude::*;
2use crate::{Color, Length, NonNegative, NoneOr};
3
4#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[parse(all_must_occur)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
12#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
13#[derive(csskit_derives::NodeWithMetadata)]
14pub struct SpreadShadow<'a> {
15 pub color: Option<Color<'a>>,
16 pub offset: NoneOr<(Length, Length)>,
17 pub blur: Option<NonNegative<Length>>,
18 pub spread: Option<Length>,
19 pub position: Option<ShadowPosition>,
20}
21
22#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
24#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
25#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(skip))]
26#[derive(csskit_derives::NodeWithMetadata)]
27pub enum ShadowPosition {
28 #[atom(CssAtomSet::Inset)]
29 Inset(T![Ident]),
30 #[atom(CssAtomSet::Outset)]
31 Outset(T![Ident]),
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37 use crate::CssAtomSet;
38 use css_parse::{assert_parse, assert_parse_error, assert_peek_false};
39
40 #[test]
41 fn size_test() {
42 assert_eq!(std::mem::size_of::<SpreadShadow>(), 104);
43 }
44
45 #[test]
46 fn test_offset_none() {
47 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "none");
48 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "none 5px");
49 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "none 5px 3px");
50 }
51
52 #[test]
53 fn test_lengths() {
54 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "0 0");
55 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "0 0 0");
56 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "0 0 0 0");
57 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "10px 20px");
58 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "10px 20px 5px");
59 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "10px 20px 5px 3px");
60 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "red 10px 20px");
61 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "10px 20px inset");
62 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "10px 20px outset");
63 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "10px 20px 5px inset");
64 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "10px 20px 5px 3px inset");
65 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "red 10px 20px inset");
66 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "0 0 0 .2rem rgba(0,123,255,.25)");
67 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "0 1px 1px rgba(0,0,0,.075)inset");
68 }
69
70 #[test]
71 fn test_leading_position() {
72 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "inset 10px 20px");
73 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "inset 0 1px 1px rgba(0,0,0,.075)");
74 assert_parse!(CssAtomSet::ATOMS, SpreadShadow, "outset 10px 20px");
75 }
76
77 #[test]
78 fn test_errors() {
79 assert_peek_false!(CssAtomSet::ATOMS, SpreadShadow, "");
80 assert_parse_error!(CssAtomSet::ATOMS, SpreadShadow, "10px");
81 assert_parse_error!(CssAtomSet::ATOMS, SpreadShadow, "red");
82 assert_parse_error!(CssAtomSet::ATOMS, SpreadShadow, "inset");
83 assert_parse_error!(CssAtomSet::ATOMS, SpreadShadow, "outset");
84 assert_parse_error!(CssAtomSet::ATOMS, SpreadShadow, "10px 20px -5px");
85 assert_parse_error!(CssAtomSet::ATOMS, SpreadShadow, "10px 20px 5px 3px 7px");
86 }
87}