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<'cmt, 's: 'cmt> Parse<'cmt, 's> for ScopeEnd<'s> {
13 fn parse(input: &mut Parser<'cmt, 's>) -> PResult<Self> {
14 let to_span = match bump!(input) {
15 TokenWithSpan {
16 token: Token::Ident(ident),
17 span,
18 } if ident.name().eq_ignore_ascii_case("to") => span,
19 TokenWithSpan { span, .. } => {
20 return Err(Error {
21 kind: ErrorKind::ExpectScopeTo,
22 span,
23 });
24 }
25 };
26
27 let (_, lparen_span) = expect!(input, LParen);
28 let selector = input.parse()?;
29 let (_, Span { end, .. }) = expect!(input, RParen);
30
31 let span = Span {
32 start: to_span.start,
33 end,
34 };
35 Ok(ScopeEnd {
36 to_span,
37 lparen_span,
38 selector,
39 span,
40 })
41 }
42}
43
44impl<'cmt, 's: 'cmt> Parse<'cmt, 's> for ScopePrelude<'s> {
46 fn parse(input: &mut Parser<'cmt, 's>) -> PResult<Self> {
47 let start = if let Token::LParen(..) = peek!(input).token {
48 Some(input.parse::<ScopeStart>()?)
49 } else {
50 None
51 };
52 let end = match &peek!(input).token {
53 Token::Ident(ident) if ident.name().eq_ignore_ascii_case("to") => {
54 Some(input.parse::<ScopeEnd>()?)
55 }
56 _ => None,
57 };
58
59 match (start, end) {
60 (Some(start), Some(end)) => {
61 let span = Span {
62 start: start.span.start,
63 end: end.span.end,
64 };
65 Ok(ScopePrelude::Both(ScopeStartWithEnd { start, end, span }))
66 }
67 (Some(start), None) => Ok(ScopePrelude::StartOnly(start)),
68 (None, Some(end)) => Ok(ScopePrelude::EndOnly(end)),
69 (None, None) => {
70 use crate::{token::LParen, tokenizer::TokenSymbol};
71 let TokenWithSpan { token, span } = bump!(input);
72 Err(Error {
73 kind: ErrorKind::Unexpected(LParen::symbol(), token.symbol()),
74 span,
75 })
76 }
77 }
78 }
79}
80
81impl<'cmt, 's: 'cmt> Parse<'cmt, 's> for ScopeStart<'s> {
82 fn parse(input: &mut Parser<'cmt, 's>) -> PResult<Self> {
83 let (_, Span { start, .. }) = expect!(input, LParen);
84 let selector = input.parse()?;
85 let (_, Span { end, .. }) = expect!(input, RParen);
86
87 Ok(ScopeStart {
88 selector,
89 span: Span { start, end },
90 })
91 }
92}