oxc_css_parser/parser/at_rule/
scope.rs1use super::Parser;
2use crate::{
3 Parse,
4 ast::*,
5 bump,
6 error::{Error, ErrorKind, PResult},
7 expect, peek,
8 pos::Span,
9 tokenizer::{Token, TokenWithSpan},
10};
11
12impl<'a> Parse<'a> for ScopeEnd<'a> {
13 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
14 let to_span = match bump!(input) {
15 TokenWithSpan { token: Token::Ident(ident), span }
16 if ident.name().eq_ignore_ascii_case("to") =>
17 {
18 span
19 }
20 TokenWithSpan { span, .. } => {
21 return Err(Error { kind: ErrorKind::ExpectScopeTo, span });
22 }
23 };
24
25 let (_, lparen_span) = expect!(input, LParen);
26 let selector = input.parse()?;
27 let (_, Span { end, .. }) = expect!(input, RParen);
28
29 let span = Span { start: to_span.start, end };
30 Ok(ScopeEnd { to_span, lparen_span, selector, span })
31 }
32}
33
34impl<'a> Parse<'a> for ScopePrelude<'a> {
36 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
37 let start = if let Token::LParen(..) = peek!(input).token {
38 Some(input.parse::<ScopeStart>()?)
39 } else {
40 None
41 };
42 let end = match &peek!(input).token {
43 Token::Ident(ident) if ident.name().eq_ignore_ascii_case("to") => {
44 Some(input.parse::<ScopeEnd>()?)
45 }
46 _ => None,
47 };
48
49 match (start, end) {
50 (Some(start), Some(end)) => {
51 let span = Span { start: start.span.start, end: end.span.end };
52 Ok(ScopePrelude::Both(ScopeStartWithEnd { start, end, span }))
53 }
54 (Some(start), None) => Ok(ScopePrelude::StartOnly(start)),
55 (None, Some(end)) => Ok(ScopePrelude::EndOnly(end)),
56 (None, None) => {
57 use crate::{token::LParen, tokenizer::TokenSymbol};
58 let TokenWithSpan { token, span } = bump!(input);
59 Err(Error { kind: ErrorKind::Unexpected(LParen::symbol(), token.symbol()), span })
60 }
61 }
62 }
63}
64
65impl<'a> Parse<'a> for ScopeStart<'a> {
66 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
67 let (_, Span { start, .. }) = expect!(input, LParen);
68 let selector = input.parse()?;
69 let (_, Span { end, .. }) = expect!(input, RParen);
70
71 Ok(ScopeStart { selector, span: Span { start, end } })
72 }
73}