Skip to main content

oxc_css_parser/
error.rs

1//! Error management.
2
3use crate::pos::Span;
4#[cfg(feature = "serialize")]
5use serde::Serialize;
6use std::fmt::Display;
7
8#[derive(Clone, Debug)]
9#[cfg_attr(feature = "serialize", derive(Serialize))]
10#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))]
11pub struct Error {
12    pub kind: ErrorKind,
13    pub span: Span,
14}
15
16#[derive(Clone, Debug)]
17#[cfg_attr(feature = "serialize", derive(Serialize))]
18pub enum ErrorKind {
19    Unexpected(/* expected */ &'static str, /* actual */ &'static str),
20    ExpectOneOf(/* expected */ Vec<&'static str>, /* actual */ &'static str),
21
22    UnknownToken,
23    InvalidNumber,
24    InvalidEscape,
25    InvalidHash,
26    ExpectRightBraceForLessVar,
27    UnexpectedLinebreak,
28    UnexpectedEof,
29    UnterminatedString,
30
31    ExpectRule,
32    UnexpectedWhitespace,
33    UnexpectedWhitespaceOrComments,
34    ExpectSimpleSelector,
35    ExpectTypeSelector,
36    ExpectIdSelector,
37    ExpectWqName,
38    ExpectAttributeSelectorMatcher,
39    ExpectAttributeSelectorValue,
40    ExpectComponentValue,
41    ExpectSassExpression,
42    ExpectDedentOrEof,
43    ExpectString,
44    ExpectUrl,
45    InvalidUrl,
46    UnexpectedTemplateInCss,
47    ExpectMediaFeatureComparison,
48    ExpectMediaAnd,
49    ExpectMediaOr,
50    ExpectMediaNot,
51    ExpectContainerConditionAnd,
52    ExpectContainerConditionOr,
53    ExpectContainerConditionNot,
54    ExpectStyleConditionAnd,
55    ExpectStyleConditionOr,
56    ExpectStyleConditionNot,
57    ExpectStyleQuery,
58    ExpectSassKeyword(&'static str),
59    InvalidAnPlusB,
60    ExpectInteger,
61    ExpectUnsignedInteger,
62    ExpectImportantAnnotation,
63    ExpectSassUseNamespace,
64    InvalidUnicodeRange,
65    UnexpectedSassElseAtRule,
66    ExpectSassAtRootWithOrWithout,
67    ExpectNthOf,
68    ExpectKeyframeBlock,
69    MixedDelimiterKindInLessMixin,
70    ExpectLessKeyword(&'static str),
71    ExpectLessExtendRule,
72    ExpectScopeTo,
73
74    TryParseError,
75    CSSWideKeywordDisallowed,
76    MediaTypeKeywordDisallowed(String),
77    UnknownKeyframeSelectorIdent,
78    InvalidRatioDenominator,
79    ExpectMediaFeatureName,
80    ExpectDashedIdent,
81    InvalidIdSelectorName,
82    ReturnOutsideFunction,
83    MaxCodePointExceeded,
84    UnicodeRangeStartGreaterThanEnd,
85    UnexpectedNthMatcher,
86    InvalidSassFlagName(String),
87    UnexpectedSassFlag(&'static str),
88    DuplicatedSassFlag(&'static str),
89    LessGuardOnMultipleComplexSelectors,
90    UnexpectedLessMixinCall,
91    UnexpectedSimpleBlock,
92    TopLevelDeclaration,
93}
94
95impl Display for ErrorKind {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        match self {
98            Self::Unexpected(expected, actual) => {
99                write!(f, "expect token `{expected}`, but found `{actual}`")
100            }
101            Self::ExpectOneOf(expected, actual) => {
102                if let [init @ .., last] = &expected[..] {
103                    let joined = init
104                        .iter()
105                        .map(|token| format!("`{token}`"))
106                        .collect::<Vec<_>>()
107                        .join(", ");
108                    write!(f, "expect one of {joined} or `{last}`, but found `{actual}`",)
109                } else {
110                    panic!("the number of expected tokens must be at least 2")
111                }
112            }
113
114            Self::UnknownToken => write!(f, "unknown token"),
115            Self::InvalidNumber => write!(f, "invalid number"),
116            Self::InvalidEscape => write!(f, "invalid escape"),
117            Self::InvalidHash => write!(f, "invalid hash token"),
118            Self::ExpectRightBraceForLessVar => write!(f, "`}}` for Less variable is expected"),
119            Self::UnexpectedLinebreak => write!(f, "unexpected linebreak"),
120            Self::UnexpectedEof => write!(f, "unexpected end of file"),
121            Self::UnterminatedString => write!(f, "unterminated string"),
122
123            Self::ExpectRule => write!(f, "CSS rule is expected"),
124            Self::UnexpectedWhitespace => write!(f, "unexpected whitespace"),
125            Self::UnexpectedWhitespaceOrComments => write!(f, "unexpected whitespace or comments"),
126            Self::ExpectSimpleSelector => write!(f, "simple selector is expected"),
127            Self::ExpectTypeSelector => write!(f, "type selector is expected"),
128            Self::ExpectIdSelector => write!(f, "ID selector is expected"),
129            Self::ExpectWqName => write!(f, "WqName is expected"),
130            Self::ExpectAttributeSelectorMatcher => {
131                write!(f, "attribute selector matcher is expected")
132            }
133            Self::ExpectAttributeSelectorValue => write!(f, "attribute selector value is expected"),
134            Self::ExpectComponentValue => write!(f, "component value is expected"),
135            Self::ExpectSassExpression => write!(f, "Sass expression is expected"),
136            Self::ExpectDedentOrEof => write!(f, "dedentation or end of file is expected"),
137            Self::ExpectString => write!(f, "string is expected"),
138            Self::ExpectUrl => write!(f, "URL is expected"),
139            Self::InvalidUrl => write!(f, "invalid URL"),
140            Self::UnexpectedTemplateInCss => write!(f, "template isn't allowed in CSS"),
141            Self::ExpectMediaFeatureComparison => write!(f, "media feature comparison is expected"),
142            Self::ExpectMediaAnd => write!(f, "media query `and` is expected"),
143            Self::ExpectMediaOr => write!(f, "media query `or` is expected"),
144            Self::ExpectMediaNot => write!(f, "media query `not` is expected"),
145            Self::ExpectContainerConditionAnd => write!(f, "container condition `and` is expected"),
146            Self::ExpectContainerConditionOr => write!(f, "container condition `or` is expected"),
147            Self::ExpectContainerConditionNot => write!(f, "container condition `not` is expected"),
148            Self::ExpectStyleConditionAnd => write!(f, "style condition `and` is expected"),
149            Self::ExpectStyleConditionOr => write!(f, "style condition `or` is expected"),
150            Self::ExpectStyleConditionNot => write!(f, "style condition `not` is expected"),
151            Self::ExpectStyleQuery => write!(f, "style query is expected"),
152            Self::ExpectSassKeyword(keyword) => write!(f, "Sass keyword `{keyword}` is expected"),
153            Self::InvalidAnPlusB => write!(f, "invalid An+B syntax"),
154            Self::ExpectInteger => write!(f, "an integer is expected"),
155            Self::ExpectUnsignedInteger => write!(f, "unsigned integer is expected"),
156            Self::ExpectImportantAnnotation => write!(f, "`!important` is expected"),
157            Self::ExpectSassUseNamespace => {
158                write!(f, "`*` or ident for Sass namespace is expected")
159            }
160            Self::InvalidUnicodeRange => write!(f, "invalid unicode range"),
161            Self::UnexpectedSassElseAtRule => write!(f, "Sass `@else` at-rule is disallowed here"),
162            Self::ExpectSassAtRootWithOrWithout => {
163                write!(f, "Sass identifier `with` or `without` is expected")
164            }
165            Self::ExpectNthOf => write!(f, "`of` is expected"),
166            Self::ExpectKeyframeBlock => write!(f, "keyframe block is expected"),
167            Self::MixedDelimiterKindInLessMixin => write!(
168                f,
169                "using both `;` and `,` as delimiters in the same Less mixin is disallowed"
170            ),
171            Self::ExpectLessKeyword(keyword) => write!(f, "Less keyword `{keyword}` is expected"),
172            Self::ExpectLessExtendRule => write!(f, "Less extend rule is expected"),
173            Self::ExpectScopeTo => write!(f, "keyword `to` of `@scope` at-rule is expected"),
174
175            Self::TryParseError => unreachable!(),
176            Self::CSSWideKeywordDisallowed => {
177                write!(f, "using CSS wide keyword as identifier is disallowed")
178            }
179            Self::MediaTypeKeywordDisallowed(keyword) => {
180                write!(f, "keyword `{keyword}` as media type is disallowed")
181            }
182            Self::UnknownKeyframeSelectorIdent => write!(f, "unknown keyframe selector"),
183            Self::InvalidRatioDenominator => write!(f, "ratio denominator is invalid"),
184            Self::ExpectMediaFeatureName => write!(f, "media feature name is expected"),
185            Self::ExpectDashedIdent => write!(f, "dashed identifier is expected"),
186            Self::InvalidIdSelectorName => write!(f, "invalid ID selector name"),
187            Self::ReturnOutsideFunction => write!(f, "`@return` is disallowed outside function"),
188            Self::MaxCodePointExceeded => {
189                write!(f, "unicode range end value exceeds max allowed code point")
190            }
191            Self::UnicodeRangeStartGreaterThanEnd => {
192                write!(f, "unicode range start value can't greater than end value")
193            }
194            Self::UnexpectedNthMatcher => {
195                write!(f, "elements matcher is allowed in `:nth-child` and `:nth-last-child` only")
196            }
197            Self::InvalidSassFlagName(flag) => write!(f, "invalid Sass flag name `{flag}`"),
198            Self::UnexpectedSassFlag(flag) => write!(f, "Sass flag `!{flag}` is disallowed"),
199            Self::DuplicatedSassFlag(flag) => write!(f, "duplicated Sass flag `!{flag}`"),
200            Self::LessGuardOnMultipleComplexSelectors => {
201                write!(f, "Less guards are only allowed on a single complex selector")
202            }
203            Self::UnexpectedLessMixinCall => write!(f, "Less mixin call is disallowed"),
204            Self::UnexpectedSimpleBlock => write!(f, "simple block is disallowed"),
205            Self::TopLevelDeclaration => write!(f, "declaration at top level is disallowed"),
206        }
207    }
208}
209
210pub type PResult<T> = Result<T, Error>;