oxc_css_parser/parser/at_rule/
custom_selector.rs1use super::Parser;
2use crate::{Parse, ast::*, error::PResult, pos::Span, tokenizer::Token, util};
3
4impl<'a> Parse<'a> for CustomSelector<'a> {
7 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
8 let prefix_arg = if matches!(input.cursor.peek()?.token, Token::DollarVar(..)) {
9 Some(input.parse::<CustomSelectorArg>()?)
10 } else {
11 None
12 };
13
14 let (_, colon_span) = input.cursor.expect_colon()?;
15 if let Some(prefix_arg) = &prefix_arg {
16 util::assert_no_ws_or_comment(&prefix_arg.span, &colon_span)?;
17 }
18 let name = input.parse::<Ident>()?;
19 util::assert_no_ws_or_comment(&colon_span, &name.span)?;
20
21 let args = if matches!(input.cursor.peek()?.token, Token::LParen(..)) {
22 Some(input.parse::<CustomSelectorArgs>()?)
23 } else {
24 None
25 };
26
27 let span = Span {
28 start: prefix_arg
29 .as_ref()
30 .map(|prefix_arg| prefix_arg.span.start)
31 .unwrap_or(name.span.start),
32 end: args.as_ref().map(|args| args.span.end).unwrap_or(name.span.end),
33 };
34 Ok(CustomSelector { prefix_arg, name, args, span })
35 }
36}
37
38impl<'a> Parse<'a> for CustomSelectorArg<'a> {
40 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
41 let (dollar_var, dollar_var_span) = input.cursor.expect_dollar_var()?;
42 Ok(CustomSelectorArg {
43 name: input.ident(
44 dollar_var.ident,
45 Span { start: dollar_var_span.start + 1, end: dollar_var_span.end },
46 ),
47 span: dollar_var_span,
48 })
49 }
50}
51
52impl<'a> Parse<'a> for CustomSelectorArgs<'a> {
54 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
55 let (_, Span { start, .. }) = input.cursor.expect_l_paren()?;
56
57 let mut args = input.vec();
58 let mut comma_spans = input.vec();
59 while !matches!(input.cursor.peek()?.token, Token::RParen(..)) {
60 args.push(input.parse()?);
61 if !matches!(input.cursor.peek()?.token, Token::RParen(..)) {
62 comma_spans.push(input.cursor.expect_comma()?.1);
63 }
64 }
65
66 let (_, Span { end, .. }) = input.cursor.expect_r_paren()?;
67 Ok(CustomSelectorArgs { args, comma_spans, span: Span { start, end } })
68 }
69}
70
71impl<'a> Parse<'a> for CustomSelectorPrelude<'a> {
76 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
77 let custom_selector = input.parse::<CustomSelector>()?;
78 let selector = input.parse::<SelectorList>()?;
79 let span = Span { start: custom_selector.span.start, end: selector.span.end };
80 Ok(CustomSelectorPrelude { custom_selector, selector, span })
81 }
82}