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