1use super::prelude::*;
2use crate::{CssAtomSet, types::CounterStyle};
3
4#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
6#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(skip))]
7pub enum TextFunctionContent {
8 #[atom(CssAtomSet::Content)]
9 Content(T![Ident]),
10 #[atom(CssAtomSet::Before)]
11 Before(T![Ident]),
12 #[atom(CssAtomSet::After)]
13 After(T![Ident]),
14 #[atom(CssAtomSet::FirstLetter)]
15 FirstLetter(T![Ident]),
16}
17
18#[derive(Parse, Peek, ToCursors, IntoCursor, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
20pub enum TargetCounterKind {
21 String(T![String]),
22 Url(T![Url]),
23}
24
25#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
32#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
33pub enum Target<'a> {
34 TargetCounter(TargetCounterFunction<'a>),
37 TargetCounters(TargetCountersFunction<'a>),
40 TargetText(TargetTextFunction),
43}
44
45#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
46#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
47#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
48pub struct TargetCounterFunction<'a> {
49 #[atom(CssAtomSet::TargetCounter)]
50 pub name: T![Function],
51 pub params: TargetCounterParams<'a>,
52 pub close: T![')'],
53}
54
55#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
56#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
57pub struct TargetCounterParams<'a>(
58 TargetCounterKind,
59 Option<T![,]>,
60 T![Ident],
61 Option<T![,]>,
62 Option<CounterStyle<'a>>,
63);
64
65#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
66#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
67#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
68pub struct TargetCountersFunction<'a> {
69 #[atom(CssAtomSet::TargetCounters)]
70 pub name: T![Function],
71 pub params: TargetCountersParams<'a>,
72 pub close: T![')'],
73}
74
75#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
76#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
77pub struct TargetCountersParams<'a>(
78 TargetCounterKind,
79 Option<T![,]>,
80 T![Ident],
81 Option<T![,]>,
82 T![String],
83 Option<T![,]>,
84 Option<CounterStyle<'a>>,
85);
86
87#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
88#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
89#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
90pub struct TargetTextFunction {
91 #[atom(CssAtomSet::TargetText)]
92 pub name: T![Function],
93 pub params: TargetTextParams,
94 pub close: T![')'],
95}
96
97#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
98#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
99pub struct TargetTextParams(TargetCounterKind, Option<T![,]>, Option<TextFunctionContent>);
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104 use crate::CssAtomSet;
105 use css_parse::{assert_parse, assert_parse_error};
106
107 #[test]
108 fn size_test() {
109 assert_eq!(std::mem::size_of::<Target>(), 184);
110 }
111
112 #[test]
113 fn test_writes() {
114 assert_parse!(CssAtomSet::ATOMS, Target, "target-counter('foo',bar,lower-roman)");
115 assert_parse!(CssAtomSet::ATOMS, Target, "target-counters('foo',bar,'baz',lower-roman)");
116 assert_parse!(CssAtomSet::ATOMS, Target, "target-text('foo')");
117 assert_parse!(CssAtomSet::ATOMS, Target, "target-text('foo',before)");
118 }
119
120 #[test]
121 fn test_errors() {
122 assert_parse_error!(CssAtomSet::ATOMS, Target, "target-counter()");
123 assert_parse_error!(CssAtomSet::ATOMS, Target, "target-counter('foo')");
124 assert_parse_error!(CssAtomSet::ATOMS, Target, "target-counters()");
125 assert_parse_error!(CssAtomSet::ATOMS, Target, "target-counters('foo')");
126 assert_parse_error!(CssAtomSet::ATOMS, Target, "target-counters('foo',bar)");
127 assert_parse_error!(CssAtomSet::ATOMS, Target, "target-text()");
128 assert_parse_error!(CssAtomSet::ATOMS, Target, "target-text(123)");
129 }
130}