1use 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(&'static str, &'static str),
20 ExpectOneOf(Vec<&'static str>, &'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>;