css_ast/functions/
counter_functions.rs

1use super::prelude::*;
2use crate::types::CounterStyle;
3
4/// <https://drafts.csswg.org/css-lists-3/#counter-functions>
5///
6/// ```text,ignore
7/// <counter()>  =  counter( <counter-name>, <counter-style>? )
8/// ```
9#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
11#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
12pub struct CounterFunction<'a> {
13	#[atom(CssAtomSet::Counter)]
14	pub name: T![Function],
15	pub params: CounterFunctionParams<'a>,
16	pub close: T![')'],
17}
18
19#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
21pub struct CounterFunctionParams<'a>(T![Ident], Option<T![,]>, Option<CounterStyle<'a>>);
22
23/// <https://drafts.csswg.org/css-lists-3/#counter-functions>
24///
25/// ```text,ignore
26/// <counters()> = counters( <counter-name>, <string>, <counter-style>? )
27/// ```
28#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
29#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
30#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
31pub struct CountersFunction<'a> {
32	#[atom(CssAtomSet::Counters)]
33	pub name: T![Function],
34	pub params: CountersFunctionParams<'a>,
35	pub close: T![')'],
36}
37
38#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
39#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
40pub struct CountersFunctionParams<'a>(T![Ident], Option<T![,]>, T![String], Option<T![,]>, Option<CounterStyle<'a>>);
41
42// https://drafts.csswg.org/css-lists-3/#counter-functions
43// <counter> = <counter()> | <counters()>
44#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
45#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
46#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(children))]
47pub enum Counter<'a> {
48	Counter(CounterFunction<'a>),
49	Counters(CountersFunction<'a>),
50}
51
52#[cfg(test)]
53mod tests {
54	use super::*;
55	use crate::CssAtomSet;
56	use css_parse::{assert_parse, assert_parse_error};
57
58	#[test]
59	fn size_test() {
60		assert_eq!(std::mem::size_of::<Counter>(), 152);
61	}
62
63	#[test]
64	fn test_writes() {
65		assert_parse!(CssAtomSet::ATOMS, Counter, "counter(foo)");
66		assert_parse!(CssAtomSet::ATOMS, Counter, "counter(foo,upper-latin)");
67		assert_parse!(CssAtomSet::ATOMS, Counter, "counters(foo,'bar')");
68		assert_parse!(CssAtomSet::ATOMS, Counter, "counters(foo,'bar',upper-latin)");
69	}
70
71	#[test]
72	fn test_errors() {
73		assert_parse_error!(CssAtomSet::ATOMS, Counter, "counter('bar')");
74		assert_parse_error!(CssAtomSet::ATOMS, Counter, "counters('bar')");
75	}
76}