1use super::prelude::*;
2#[cfg(feature = "visitable")]
3use crate::visit::{NodeId, QueryableNode};
4use crate::{Inherits, PropertyGroup};
5use csskit_derives::*;
6use csskit_proc_macro::{node, syntax};
7
8#[node]
10#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
11#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit, queryable(skip))]
12#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
13#[derive(csskit_derives::NodeWithMetadata)]
14#[metadata(node_kinds = AtRule, used_at_rules = CounterStyle, property_kinds = Name)]
15pub struct CounterStyleRule<'a> {
16 #[cfg_attr(feature = "visitable", visit(skip))]
17 #[atom(CssAtomSet::CounterStyle)]
18 pub name: T![AtKeyword],
19 pub prelude: CounterStyleName,
20 #[metadata(block)]
21 pub block: CounterStyleRuleBlock<'a>,
22}
23
24#[cfg(feature = "visitable")]
25impl<'a> QueryableNode for CounterStyleRule<'a> {
26 const NODE_ID: NodeId = NodeId::CounterStyleRule;
27
28 fn get_property(&self, kind: PropertyKind) -> Option<Cursor> {
29 match kind {
30 PropertyKind::Name => Some(self.prelude.into()),
31 _ => None,
32 }
33 }
34}
35
36#[node]
37#[derive(
38 Parse, Peek, IntoCursor, ToSpan, SemanticEq, ToCursors, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
39)]
40#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable))]
41#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
42#[derive(csskit_derives::NodeWithMetadata)]
43pub struct CounterStyleName(T![Ident]);
44
45#[node]
46#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
47#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable))]
48#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
49#[derive(csskit_derives::NodeWithMetadata)]
50pub struct CounterStyleRuleBlock<'a>(DeclarationList<'a, CounterStyleRuleStyleValue<'a>, CssMetadata>);
51
52#[node]
53#[derive(ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
54#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
55#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
56#[derive(csskit_derives::NodeWithMetadata)]
57#[metadata(node_kinds = Declaration, property_kinds = Name)]
58pub enum CounterStyleRuleStyleValue<'a> {
59 Unknown(ComponentValues<'a>),
60 System(SystemStyleValue<'a>),
61 Symbols(SymbolsStyleValue<'a>),
62 AdditiveSymbols(AdditiveSymbolsStyleValue<'a>),
63 Negative(NegativeStyleValue<'a>),
64 Prefix(PrefixStyleValue<'a>),
65 Suffix(SuffixStyleValue<'a>),
66 Range(RangeStyleValue<'a>),
67 Pad(PadStyleValue<'a>),
68 SpeakAs(SpeakAsStyleValue<'a>),
69 Fallback(FallbackStyleValue),
70}
71
72impl<'a> DeclarationValue<'a, CssMetadata> for CounterStyleRuleStyleValue<'a> {
73 fn valid_declaration_name<I>(p: &Parser<'a, I>, c: Cursor) -> bool
74 where
75 I: Iterator<Item = Cursor> + Clone,
76 {
77 matches!(p.to_atom::<CssAtomSet>(c), CssAtomSet::InitialValue | CssAtomSet::Inherits | CssAtomSet::Syntax)
78 }
79
80 fn is_unknown(&self) -> bool {
81 matches!(self, Self::Unknown(_))
82 }
83
84 fn needs_computing(&self) -> bool {
85 matches!(self, Self::Unknown(_))
86 }
87
88 fn parse_declaration_value<I>(p: &mut Parser<'a, I>, c: Cursor) -> ParserResult<Self>
89 where
90 I: Iterator<Item = Cursor> + Clone,
91 {
92 Ok(match p.to_atom::<CssAtomSet>(c) {
93 CssAtomSet::System => Self::System(p.parse::<SystemStyleValue<'a>>()?),
94 CssAtomSet::Symbols => Self::Symbols(p.parse::<SymbolsStyleValue<'a>>()?),
95 CssAtomSet::AdditiveSymbols => Self::AdditiveSymbols(p.parse::<AdditiveSymbolsStyleValue<'a>>()?),
96 CssAtomSet::Negative => Self::Negative(p.parse::<NegativeStyleValue<'a>>()?),
97 CssAtomSet::Prefix => Self::Prefix(p.parse::<PrefixStyleValue<'a>>()?),
98 CssAtomSet::Suffix => Self::Suffix(p.parse::<SuffixStyleValue<'a>>()?),
99 CssAtomSet::Range => Self::Range(p.parse::<RangeStyleValue<'a>>()?),
100 CssAtomSet::Pad => Self::Pad(p.parse::<PadStyleValue<'a>>()?),
101 CssAtomSet::SpeakAs => Self::SpeakAs(p.parse::<SpeakAsStyleValue>()?),
102 CssAtomSet::Fallback => Self::Fallback(p.parse::<FallbackStyleValue>()?),
103 _ => Self::Unknown(p.parse::<ComponentValues<'a>>()?),
104 })
105 }
106}
107
108#[syntax(" [ <integer [0,∞]> && <symbol> ]# ")]
109#[derive(
110 Peek, Parse, ToCursors, ToSpan, DeclarationMetadata, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
111)]
112#[declaration_metadata(initial = "n/a", inherits = False, property_group = CounterStyle)]
113#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
114#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
115#[derive(csskit_derives::NodeWithMetadata)]
116pub struct AdditiveSymbolsStyleValue<'a>;
117
118#[node]
119#[derive(
120 Peek, Parse, ToCursors, ToSpan, DeclarationMetadata, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
121)]
122#[declaration_metadata(initial = "n/a", inherits = False, property_group = CounterStyle)]
123#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
124#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
125#[derive(csskit_derives::NodeWithMetadata)]
126pub struct FallbackStyleValue(CounterStyleName);
127
128#[syntax(" <symbol> <symbol>? ")]
129#[derive(
130 Peek, Parse, ToCursors, ToSpan, DeclarationMetadata, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
131)]
132#[declaration_metadata(initial = "n/a", inherits = False, property_group = CounterStyle)]
133#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
134#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
135#[derive(csskit_derives::NodeWithMetadata)]
136pub struct NegativeStyleValue<'a>;
137
138#[syntax(" <integer [0,∞]> && <symbol> ")]
139#[derive(
140 Peek, Parse, ToCursors, ToSpan, DeclarationMetadata, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
141)]
142#[declaration_metadata(initial = "n/a", inherits = False, property_group = CounterStyle)]
143#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
144#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
145#[derive(csskit_derives::NodeWithMetadata)]
146pub struct PadStyleValue<'a>;
147
148#[syntax(" <symbol> ")]
149#[derive(
150 Peek, Parse, ToCursors, ToSpan, DeclarationMetadata, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
151)]
152#[declaration_metadata(initial = "n/a", inherits = False, property_group = CounterStyle)]
153#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
154#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
155#[derive(csskit_derives::NodeWithMetadata)]
156pub struct PrefixStyleValue<'a>;
157
158#[syntax(" [ [ <integer> | infinite ]{2} ]# | auto ")]
159#[derive(
160 Peek, Parse, ToCursors, ToSpan, DeclarationMetadata, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
161)]
162#[declaration_metadata(initial = "n/a", inherits = False, property_group = CounterStyle)]
163#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
164#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
165#[derive(csskit_derives::NodeWithMetadata)]
166pub struct RangeStyleValue<'a>;
167
168#[syntax(" auto | bullets | numbers | words | spell-out | <counter-style-name> ")]
169#[derive(
170 Peek, Parse, ToCursors, ToSpan, DeclarationMetadata, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
171)]
172#[declaration_metadata(initial = "n/a", inherits = False, property_group = CounterStyle)]
173#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
174#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
175#[derive(csskit_derives::NodeWithMetadata)]
176pub enum SpeakAsStyleValue<'a> {}
177
178#[syntax(" <symbol> ")]
179#[derive(
180 Peek, Parse, ToCursors, ToSpan, DeclarationMetadata, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
181)]
182#[declaration_metadata(initial = "n/a", inherits = False, property_group = CounterStyle)]
183#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
184#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
185#[derive(csskit_derives::NodeWithMetadata)]
186pub struct SuffixStyleValue<'a>;
187
188#[syntax(" <symbol>+ ")]
189#[derive(
190 Peek, Parse, ToCursors, ToSpan, DeclarationMetadata, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
191)]
192#[declaration_metadata(initial = "n/a", inherits = False, property_group = CounterStyle)]
193#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
194#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
195#[derive(csskit_derives::NodeWithMetadata)]
196pub struct SymbolsStyleValue<'a>;
197
198#[syntax(
199 " cyclic | numeric | alphabetic | symbolic | additive | [fixed <integer>?] | [ extends <counter-style-name> ] "
200)]
201#[derive(
202 Peek, Parse, ToCursors, ToSpan, DeclarationMetadata, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
203)]
204#[declaration_metadata(initial = "n/a", inherits = False, property_group = CounterStyle)]
205#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
206#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
207#[derive(csskit_derives::NodeWithMetadata)]
208pub enum SystemStyleValue<'a> {}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213 use css_parse::assert_parse;
214
215 #[test]
216 fn test_writes() {
217 assert_parse!(CssAtomSet::ATOMS, CounterStyleRule, "@counter-style thumbs {}");
218 }
219}