1use super::prelude::*;
2use crate::{AtPosition, CalcableValue};
3
4#[node]
10#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
12#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
13#[derive(csskit_derives::NodeWithMetadata)]
14pub struct RayFunction<'a> {
15 #[atom(CssAtomSet::Ray)]
16 pub name: T![Function],
17 pub params: RayFunctionParams<'a>,
18 #[semantic_eq(skip)]
19 pub close: T![')'],
20}
21
22#[node]
28#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
29#[parse(all_must_occur)]
30#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
31#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
32#[derive(csskit_derives::NodeWithMetadata)]
33pub struct RayFunctionParams<'a> {
34 pub angle: CalcableValue<'a, Angle>,
35 pub size: Option<RaySize>,
36 #[atom(CssAtomSet::Contain)]
37 pub contain: Option<T![Ident]>,
38 pub at: Option<AtPosition<'a>>,
39}
40
41#[node]
47#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
48#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
49#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(skip))]
50#[derive(csskit_derives::NodeWithMetadata)]
51pub enum RaySize {
52 #[atom(CssAtomSet::ClosestSide)]
53 ClosestSide(T![Ident]),
54 #[atom(CssAtomSet::ClosestCorner)]
55 ClosestCorner(T![Ident]),
56 #[atom(CssAtomSet::FarthestSide)]
57 FarthestSide(T![Ident]),
58 #[atom(CssAtomSet::FarthestCorner)]
59 FarthestCorner(T![Ident]),
60 #[atom(CssAtomSet::Sides)]
61 Sides(T![Ident]),
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67 use crate::CssAtomSet;
68 use css_parse::{assert_parse, assert_parse_error, assert_peek_false};
69
70 #[test]
71 fn test_parses() {
72 assert_parse!(CssAtomSet::ATOMS, RayFunction, "ray(45deg)");
73 assert_parse!(CssAtomSet::ATOMS, RayFunction, "ray(45deg closest-side)");
74 assert_parse!(CssAtomSet::ATOMS, RayFunction, "ray(contain 45deg)");
75 assert_parse!(CssAtomSet::ATOMS, RayFunction, "ray(45deg sides contain)");
76 assert_parse!(CssAtomSet::ATOMS, RayFunction, "ray(farthest-corner 45deg contain at center)");
77 assert_parse!(CssAtomSet::ATOMS, RayFunction, "ray(at 50% 50% 0.25turn)");
78 assert_parse!(CssAtomSet::ATOMS, RayFunction, "ray(calc(45deg + 1rad))");
79 assert_parse!(CssAtomSet::ATOMS, RayFunction, "ray(var(--angle))");
80 }
81
82 #[test]
83 fn test_errors() {
84 assert_peek_false!(CssAtomSet::ATOMS, RayFunction, "circle(45deg)");
85 assert_parse_error!(CssAtomSet::ATOMS, RayFunction, "ray()");
86 assert_parse_error!(CssAtomSet::ATOMS, RayFunction, "ray(contain)");
87 assert_parse_error!(CssAtomSet::ATOMS, RayFunction, "ray(45deg 45deg)");
88 assert_parse_error!(CssAtomSet::ATOMS, RayFunction, "ray(45deg sides sides)");
89 }
90}