1use crate::diagnostics;
2use css_parse::{Cursor, Parse, Parser, Peek, Result as ParserResult, keyword_set};
3use csskit_derives::{ToCursors, ToSpan, Visitable};
4
5#[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});