css_ast/functions/
counter_functions.rs

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