css_ast/types/
position_area.rs

1use crate::diagnostics;
2use css_parse::{Cursor, Parse, Parser, Peek, Result as ParserResult, keyword_set};
3use csskit_derives::{ToCursors, ToSpan, Visitable};
4
5// https://drafts.csswg.org/css-anchor-position-1/#typedef-position-area
6// <position-area> = [
7//   [ left | center | right | span-left | span-right
8//   | x-start | x-end | span-x-start | span-x-end
9//   | x-self-start | x-self-end | span-x-self-start | span-x-self-end
10//   | span-all ]
11//   ||
12//   [ top | center | bottom | span-top | span-bottom
13//   | y-start | y-end | span-y-start | span-y-end
14//   | y-self-start | y-self-end | span-y-self-start | span-y-self-end
15//   | span-all ]
16// |
17//   [ block-start | center | block-end | span-block-start | span-block-end | span-all ]
18//   ||
19//   [ inline-start | center | inline-end | span-inline-start | span-inline-end
20//   | span-all ]
21// |
22//   [ self-block-start | center | self-block-end | span-self-block-start
23//   | span-self-block-end | span-all ]
24//   ||
25//   [ self-inline-start | center | self-inline-end | span-self-inline-start
26//   | span-self-inline-end | span-all ]
27// |
28//   [ start | center | end | span-start | span-end | span-all ]{1,2}
29// |
30//   [ self-start | center | self-end | span-self-start | span-self-end | span-all ]{1,2}
31// ]
32#[derive(ToCursors, ToSpan, Visitable, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
33#[cfg_attr(feature = "serde", derive(serde::Serialize), serde(rename_all = "kebab-case"))]
34#[visit(self)]
35pub enum PositionArea {
36	Physical(Option<PositionAreaPhsyicalHorizontal>, Option<PositionAreaPhsyicalVertical>),
37	Logical(Option<PositionAreaBlock>, Option<PositionAreaInline>),
38	SelfLogical(Option<PositionAreaSelfBlock>, Option<PositionAreaSelfInline>),
39	Position(PositionAreaPosition, Option<PositionAreaPosition>),
40	SelfPosition(PositionAreaSelfPosition, Option<PositionAreaSelfPosition>),
41}
42
43impl<'a> Peek<'a> for PositionArea {
44	fn peek(p: &Parser<'a>, c: Cursor) -> bool {
45		PositionAreaPhsyicalVertical::peek(p, c)
46			|| PositionAreaPhsyicalHorizontal::peek(p, c)
47			|| PositionAreaBlock::peek(p, c)
48			|| PositionAreaInline::peek(p, c)
49			|| PositionAreaSelfBlock::peek(p, c)
50			|| PositionAreaSelfInline::peek(p, c)
51			|| PositionAreaPosition::peek(p, c)
52			|| PositionAreaSelfPosition::peek(p, c)
53	}
54}
55
56impl<'a> Parse<'a> for PositionArea {
57	fn parse(p: &mut Parser<'a>) -> ParserResult<Self> {
58		if let Some(first) = p.parse_if_peek::<PositionAreaPosition>()? {
59			Ok(Self::Position(first, p.parse_if_peek::<PositionAreaPosition>()?))
60		} else if let Some(first) = p.parse_if_peek::<PositionAreaSelfPosition>()? {
61			Ok(Self::SelfPosition(first, p.parse_if_peek::<PositionAreaSelfPosition>()?))
62		} else if let Some(block) = p.parse_if_peek::<PositionAreaBlock>()? {
63			Ok(Self::Logical(Some(block), p.parse_if_peek::<PositionAreaInline>()?))
64		} else if let Some(inline) = p.parse_if_peek::<PositionAreaInline>()? {
65			Ok(Self::Logical(p.parse_if_peek::<PositionAreaBlock>()?, Some(inline)))
66		} else if let Some(block) = p.parse_if_peek::<PositionAreaSelfBlock>()? {
67			Ok(Self::SelfLogical(Some(block), p.parse_if_peek::<PositionAreaSelfInline>()?))
68		} else if let Some(inline) = p.parse_if_peek::<PositionAreaSelfInline>()? {
69			Ok(Self::SelfLogical(p.parse_if_peek::<PositionAreaSelfBlock>()?, Some(inline)))
70		} else if let Some(horizontal) = p.parse_if_peek::<PositionAreaPhsyicalHorizontal>()? {
71			Ok(Self::Physical(Some(horizontal), p.parse_if_peek::<PositionAreaPhsyicalVertical>()?))
72		} else if let Some(vertical) = p.parse_if_peek::<PositionAreaPhsyicalVertical>()? {
73			Ok(Self::Physical(p.parse_if_peek::<PositionAreaPhsyicalHorizontal>()?, Some(vertical)))
74		} else {
75			Err(diagnostics::Unexpected(p.next()))?
76		}
77	}
78}
79
80keyword_set!(pub enum PositionAreaPhsyicalHorizontal {
81	Left: "left",
82	Center: "center",
83	Right: "right",
84	SpanLeft: "span-left",
85	SpanRight: "span-right",
86	XStart: "x-start",
87	XEnd: "x-end",
88	SpanXStart: "span-x-start",
89	SpanXEnd: "span-x-end",
90	XSelfStart: "x-self-start",
91	XSelfEnd: "x-self-end",
92	SpanXSelfStart: "span-x-self-start",
93	SpanXSelfEnd: "span-x-self-end",
94	SpanAll: "span-all",
95});
96
97keyword_set!(pub enum PositionAreaPhsyicalVertical {
98	Top: "top",
99	Center: "center",
100	Bottom: "bottom",
101	SpanTop: "span-top",
102	SpanBottom: "span-bottom",
103	YStart: "y-start",
104	YEnd: "y-end",
105	SpanYStart: "span-y-start",
106	SpanYEnd: "span-y-end",
107	YSelfStart: "y-self-start",
108	YSelfEnd: "y-self-end",
109	SpanYSelfStart: "span-y-self-start",
110	SpanYSelfEnd: "span-y-self-end",
111	SpanAll: "span-all",
112});
113
114keyword_set!(pub enum PositionAreaBlock {
115	BlockStart: "block-start",
116	Center: "center",
117	BlockEnd: "block-end",
118	SpanBlockStart: "span-block-start",
119	SpanBlockEnd: "span-block-end",
120	SpanAll: "span-all",
121});
122
123keyword_set!(pub enum PositionAreaInline {
124	InlineStart: "inline-start",
125	Center: "center",
126	InlineEnd: "inline-end",
127	SpanInlineStart: "span-inline-start",
128	SpanInlineEnd: "span-inline-end",
129	SpanAll: "span-all",
130});
131
132keyword_set!(pub enum PositionAreaSelfBlock {
133	SelfBlockStart: "self-block-start",
134	Center: "center",
135	SelfBlockEnd: "self-block-end",
136	SpanSelfBlockStart: "span-self-block-start",
137	SpanSelfBlockEnd: "span-self-block-end",
138	SpanAll: "span-all",
139});
140
141keyword_set!(pub enum PositionAreaSelfInline {
142	SelfInlineStart: "self-inline-start",
143	Center: "center",
144	SelfInlineEnd: "self-inline-end",
145	SpanSelfInlineStart: "span-self-inline-start",
146	SpanSelfInlineEnd: "span-self-inline-end",
147	SpanAll: "span-all",
148});
149
150keyword_set!(pub enum PositionAreaPosition {
151	Start: "start",
152	Center: "center",
153	End: "end",
154	SpanStart: "span-start",
155	SpanEnd: "span-end",
156	SpanAll: "span-all",
157});
158
159keyword_set!(pub enum PositionAreaSelfPosition {
160	SelfStart: "self-start",
161	Center: "center",
162	SelfEnd: "self-end",
163	SpanSelfStart: "span-self-start",
164	SpanSelfEnd: "span-self-end",
165	SpanAll: "span-all",
166});