oxc_css_parser/parser/at_rule/
import.rs1use super::Parser;
2use crate::{
3 Parse, Syntax, arena_vec,
4 ast::*,
5 bump,
6 error::{Error, ErrorKind, PResult},
7 expect, expect_without_ws_or_comments, peek,
8 pos::{Span, Spanned},
9 tokenizer::{Token, TokenWithSpan},
10};
11
12impl<'a> Parse<'a> for ImportPrelude<'a> {
14 fn parse(input: &mut Parser<'a>) -> PResult<Self> {
15 let href = match &peek!(input).token {
16 Token::Str(..) | Token::StrTemplate(..) => input.parse().map(ImportPreludeHref::Str)?,
17 _ => match input.try_parse(Url::parse) {
18 Ok(url) => ImportPreludeHref::Url(url),
19 Err(error) if matches!(input.syntax, Syntax::Scss | Syntax::Sass) => {
23 let (function_name, function_name_span) = expect!(input, Ident);
24 let function_name = input.ident(function_name, function_name_span);
25 if !function_name.name.eq_ignore_ascii_case("url") {
26 return Err(error);
27 }
28 input
29 .parse_function(InterpolableIdent::Literal(function_name))
30 .map(ImportPreludeHref::Function)
31 .map_err(|_| error)?
32 }
33 Err(error) => return Err(error),
34 },
35 };
36 let mut span = href.span().clone();
37
38 let layer = match &peek!(input).token {
39 Token::Ident(ident) if ident.name().eq_ignore_ascii_case("layer") => {
40 let ident = input.parse::<Ident>()?;
41 let layer = match peek!(input) {
42 TokenWithSpan { token: Token::LParen(..), span }
43 if span.start == ident.span.end =>
44 {
45 bump!(input);
46 let args = arena_vec!(input; input.parse().map(ComponentValue::LayerName)?);
47 let end = expect!(input, RParen).1.end;
48 let span = Span { start: ident.span.start, end };
49 ImportPreludeLayer::WithName(Function {
50 name: FunctionName::Ident(InterpolableIdent::Literal(ident)),
51 args,
52 span,
53 })
54 }
55 _ => ImportPreludeLayer::Empty(ident),
56 };
57 span.end = layer.span().end;
58 Some(layer)
59 }
60 _ => None,
61 };
62
63 let supports = input.try_parse(|parser| {
64 let (ident, span) = expect!(parser, Ident);
65 if !ident.name().eq_ignore_ascii_case("supports") {
66 return Err(Error { kind: ErrorKind::TryParseError, span });
67 }
68
69 expect_without_ws_or_comments!(parser, LParen);
70
71 let kind = if let Ok(supports_condition) = parser.try_parse(SupportsCondition::parse) {
72 ImportPreludeSupportsKind::SupportsCondition(supports_condition)
73 } else {
74 parser.parse().map(ImportPreludeSupportsKind::Declaration)?
75 };
76 let (_, Span { end, .. }) = expect!(parser, RParen);
77 Ok(ImportPreludeSupports { kind, span: Span { start: span.start, end } })
78 });
79 if let Ok(supports) = &supports {
80 span.end = supports.span().end;
81 }
82
83 let media = if matches!(peek!(input).token, Token::Semicolon(..)) {
84 None
85 } else {
86 let media = input.parse::<MediaQueryList>()?;
87 span.end = media.span.end;
88 Some(media)
89 };
90
91 Ok(ImportPrelude { href, layer, supports: supports.ok(), media, span })
92 }
93}