css_ast/functions/
symbols_function.rs

1use super::prelude::*;
2use crate::{CssAtomSet, types::Image};
3
4/// <https://drafts.csswg.org/css-counter-styles-3/#funcdef-symbols>
5///
6/// ```text,ignore
7/// symbols() = symbols( <symbols-type>? [ <string> | <image> ]+ )
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))]
12#[derive(csskit_derives::NodeWithMetadata)]
13pub struct SymbolsFunction<'a> {
14	#[atom(CssAtomSet::Symbols)]
15	pub name: T![Function],
16	pub params: SymbolsFunctionParams<'a>,
17	pub close: T![')'],
18}
19
20#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
22#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
23#[derive(csskit_derives::NodeWithMetadata)]
24pub struct SymbolsFunctionParams<'a> {
25	pub symbols_type: Option<SymbolsType>,
26	pub symbols: Vec<'a, Symbol<'a>>,
27}
28
29/// <https://drafts.csswg.org/css-counter-styles-3/#typedef-symbols-type>
30///
31/// ```text,ignore
32/// <symbols-type> = cyclic | numeric | alphabetic | symbolic | fixed
33/// ```
34#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
35#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
36#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(skip))]
37#[derive(csskit_derives::NodeWithMetadata)]
38pub enum SymbolsType {
39	#[atom(CssAtomSet::Cyclic)]
40	Cyclic(T![Ident]),
41	#[atom(CssAtomSet::Numeric)]
42	Numeric(T![Ident]),
43	#[atom(CssAtomSet::Alphabetic)]
44	Alphabetic(T![Ident]),
45	#[atom(CssAtomSet::Symbolic)]
46	Symbolic(T![Ident]),
47	#[atom(CssAtomSet::Fixed)]
48	Fixed(T![Ident]),
49}
50
51/// <https://drafts.csswg.org/css-counter-styles-3/#funcdef-symbols>
52///
53/// A single Symbol from the `<symbols()>` syntax
54///
55/// ```text,ignore
56/// <string> | <image>
57/// ```
58#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
59#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
60#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(children))]
61#[derive(csskit_derives::NodeWithMetadata)]
62#[allow(clippy::large_enum_variant)] // TODO: Box or shrink Image
63pub enum Symbol<'a> {
64	#[cfg_attr(feature = "visitable", visit(skip))]
65	String(T![String]),
66	Image(Image<'a>),
67}
68
69#[cfg(test)]
70mod tests {
71	use super::*;
72	use crate::CssAtomSet;
73	use css_parse::assert_parse;
74
75	#[test]
76	fn size_test() {
77		assert_eq!(std::mem::size_of::<SymbolsFunction>(), 72);
78		assert_eq!(std::mem::size_of::<Symbol>(), 208);
79		assert_eq!(std::mem::size_of::<SymbolsType>(), 16);
80	}
81
82	#[test]
83	fn test_writes() {
84		assert_parse!(CssAtomSet::ATOMS, SymbolsFunction, "symbols(symbolic'+')");
85		assert_parse!(CssAtomSet::ATOMS, SymbolsFunction, "symbols(symbolic'*''†''‡')");
86	}
87}