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    UnexpectedSemicolonInSass,
92    UnexpectedSimpleBlock,
93    TopLevelDeclaration,
94}
95
96impl Display for ErrorKind {
97    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98        match self {
99            Self::Unexpected(expected, actual) => {
100                write!(f, "expect token `{expected}`, but found `{actual}`")
101            }
102            Self::ExpectOneOf(expected, actual) => {
103                if let [init @ .., last] = &expected[..] {
104                    let joined = init
105                        .iter()
106                        .map(|token| format!("`{token}`"))
107                        .collect::<Vec<_>>()
108                        .join(", ");
109                    write!(f, "expect one of {joined} or `{last}`, but found `{actual}`",)
110                } else {
111                    panic!("the number of expected tokens must be at least 2")
112                }
113            }
114
115            Self::UnknownToken => write!(f, "unknown token"),
116            Self::InvalidNumber => write!(f, "invalid number"),
117            Self::InvalidEscape => write!(f, "invalid escape"),
118            Self::InvalidHash => write!(f, "invalid hash token"),
119            Self::ExpectRightBraceForLessVar => write!(f, "`}}` for Less variable is expected"),
120            Self::UnexpectedLinebreak => write!(f, "unexpected linebreak"),
121            Self::UnexpectedEof => write!(f, "unexpected end of file"),
122            Self::UnterminatedString => write!(f, "unterminated string"),
123
124            Self::ExpectRule => write!(f, "CSS rule is expected"),
125            Self::UnexpectedWhitespace => write!(f, "unexpected whitespace"),
126            Self::UnexpectedWhitespaceOrComments => write!(f, "unexpected whitespace or comments"),
127            Self::ExpectSimpleSelector => write!(f, "simple selector is expected"),
128            Self::ExpectTypeSelector => write!(f, "type selector is expected"),
129            Self::ExpectIdSelector => write!(f, "ID selector is expected"),
130            Self::ExpectWqName => write!(f, "WqName is expected"),
131            Self::ExpectAttributeSelectorMatcher => {
132                write!(f, "attribute selector matcher is expected")
133            }
134            Self::ExpectAttributeSelectorValue => write!(f, "attribute selector value is expected"),
135            Self::ExpectComponentValue => write!(f, "component value is expected"),
136            Self::ExpectSassExpression => write!(f, "Sass expression is expected"),
137            Self::ExpectDedentOrEof => write!(f, "dedentation or end of file is expected"),
138            Self::ExpectString => write!(f, "string is expected"),
139            Self::ExpectUrl => write!(f, "URL is expected"),
140            Self::InvalidUrl => write!(f, "invalid URL"),
141            Self::UnexpectedTemplateInCss => write!(f, "template isn't allowed in CSS"),
142            Self::ExpectMediaFeatureComparison => write!(f, "media feature comparison is expected"),
143            Self::ExpectMediaAnd => write!(f, "media query `and` is expected"),
144            Self::ExpectMediaOr => write!(f, "media query `or` is expected"),
145            Self::ExpectMediaNot => write!(f, "media query `not` is expected"),
146            Self::ExpectContainerConditionAnd => write!(f, "container condition `and` is expected"),
147            Self::ExpectContainerConditionOr => write!(f, "container condition `or` is expected"),
148            Self::ExpectContainerConditionNot => write!(f, "container condition `not` is expected"),
149            Self::ExpectStyleConditionAnd => write!(f, "style condition `and` is expected"),
150            Self::ExpectStyleConditionOr => write!(f, "style condition `or` is expected"),
151            Self::ExpectStyleConditionNot => write!(f, "style condition `not` is expected"),
152            Self::ExpectStyleQuery => write!(f, "style query is expected"),
153            Self::ExpectSassKeyword(keyword) => write!(f, "Sass keyword `{keyword}` is expected"),
154            Self::InvalidAnPlusB => write!(f, "invalid An+B syntax"),
155            Self::ExpectInteger => write!(f, "an integer is expected"),
156            Self::ExpectUnsignedInteger => write!(f, "unsigned integer is expected"),
157            Self::ExpectImportantAnnotation => write!(f, "`!important` is expected"),
158            Self::ExpectSassUseNamespace => {
159                write!(f, "`*` or ident for Sass namespace is expected")
160            }
161            Self::InvalidUnicodeRange => write!(f, "invalid unicode range"),
162            Self::UnexpectedSassElseAtRule => write!(f, "Sass `@else` at-rule is disallowed here"),
163            Self::ExpectSassAtRootWithOrWithout => {
164                write!(f, "Sass identifier `with` or `without` is expected")
165            }
166            Self::ExpectNthOf => write!(f, "`of` is expected"),
167            Self::ExpectKeyframeBlock => write!(f, "keyframe block is expected"),
168            Self::MixedDelimiterKindInLessMixin => write!(
169                f,
170                "using both `;` and `,` as delimiters in the same Less mixin is disallowed"
171            ),
172            Self::ExpectLessKeyword(keyword) => write!(f, "Less keyword `{keyword}` is expected"),
173            Self::ExpectLessExtendRule => write!(f, "Less extend rule is expected"),
174            Self::ExpectScopeTo => write!(f, "keyword `to` of `@scope` at-rule is expected"),
175
176            Self::TryParseError => unreachable!(),
177            Self::CSSWideKeywordDisallowed => {
178                write!(f, "using CSS wide keyword as identifier is disallowed")
179            }
180            Self::MediaTypeKeywordDisallowed(keyword) => {
181                write!(f, "keyword `{keyword}` as media type is disallowed")
182            }
183            Self::UnknownKeyframeSelectorIdent => write!(f, "unknown keyframe selector"),
184            Self::InvalidRatioDenominator => write!(f, "ratio denominator is invalid"),
185            Self::ExpectMediaFeatureName => write!(f, "media feature name is expected"),
186            Self::ExpectDashedIdent => write!(f, "dashed identifier is expected"),
187            Self::InvalidIdSelectorName => write!(f, "invalid ID selector name"),
188            Self::ReturnOutsideFunction => write!(f, "`@return` is disallowed outside function"),
189            Self::MaxCodePointExceeded => {
190                write!(f, "unicode range end value exceeds max allowed code point")
191            }
192            Self::UnicodeRangeStartGreaterThanEnd => {
193                write!(f, "unicode range start value can't greater than end value")
194            }
195            Self::UnexpectedNthMatcher => {
196                write!(f, "elements matcher is allowed in `:nth-child` and `:nth-last-child` only")
197            }
198            Self::InvalidSassFlagName(flag) => write!(f, "invalid Sass flag name `{flag}`"),
199            Self::UnexpectedSassFlag(flag) => write!(f, "Sass flag `!{flag}` is disallowed"),
200            Self::DuplicatedSassFlag(flag) => write!(f, "duplicated Sass flag `!{flag}`"),
201            Self::LessGuardOnMultipleComplexSelectors => {
202                write!(f, "Less guards are only allowed on a single complex selector")
203            }
204            Self::UnexpectedLessMixinCall => write!(f, "Less mixin call is disallowed"),
205            Self::UnexpectedSemicolonInSass => write!(f, "semicolon in Sass is disallowed"),
206            Self::UnexpectedSimpleBlock => write!(f, "simple block is disallowed"),
207            Self::TopLevelDeclaration => write!(f, "declaration at top level is disallowed"),
208        }
209    }
210}
211
212pub type PResult<T> = Result<T, Error>;