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