Skip to main content

css_ast/functions/
ident_function.rs

1use super::prelude::*;
2use crate::{NumericValue, Value};
3
4/// <https://drafts.csswg.org/css-values-5/#ident>
5///
6/// The `ident()` function constructs a `<custom-ident>` from multiple parts.
7///
8/// ```text,ignore
9/// <ident()> = ident( <ident-arg>+ )
10/// <ident-arg> = <string> | <integer> | <ident>
11/// ```
12#[node]
13#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
15#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
16#[derive(csskit_derives::NodeWithMetadata)]
17#[metadata(declaration_kinds = Computed)]
18pub struct IdentFunction<'a> {
19	#[atom(CssAtomSet::Ident)]
20	pub name: T![Function],
21	pub args: Vec<'a, IdentArg<'a>>,
22	#[semantic_eq(skip)]
23	pub close: T![')'],
24}
25
26/// A single `<ident-arg>` inside an [`IdentFunction`].
27///
28/// The `<integer>` slot is wrapped in [`NumericValue`] so it also admits the tree-counting
29/// functions (`sibling-index()`/`sibling-count()`) and math functions, and the `<ident>` slot in
30/// [`Value`] so it admits arbitrary substitution functions, matching the spec examples such as
31/// `ident("vtl-" sibling-index())` and `ident(var(--id) "-title")`.
32///
33/// ```text,ignore
34/// <ident-arg> = <string> | <integer> | <ident>
35/// ```
36#[node]
37#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
39#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(children))]
40#[derive(csskit_derives::NodeWithMetadata)]
41pub enum IdentArg<'a> {
42	#[cfg_attr(feature = "visitable", visit(skip))]
43	String(T![String]),
44	Integer(NumericValue<'a, CSSInt>),
45	Keyword(Value<'a, T![Ident]>),
46}
47
48#[cfg(test)]
49mod tests {
50	use super::*;
51	use crate::CssAtomSet;
52	use css_parse::assert_parse;
53
54	#[test]
55	fn test_ident_function() {
56		assert_parse!(CssAtomSet::ATOMS, IdentFunction, "ident(foo)");
57		assert_parse!(CssAtomSet::ATOMS, IdentFunction, "ident('vtl-'sibling-index())");
58		assert_parse!(CssAtomSet::ATOMS, IdentFunction, "ident(var(--id))");
59		assert_parse!(CssAtomSet::ATOMS, IdentFunction, "ident(var(--id)'-title')");
60	}
61}