///|
/// What went wrong, as a closed set.
///
/// This package has no dependencies at all, and that is deliberate: the AST
/// stores a kind on every `Bogus` node, so if kinds lived beside the
/// `Diagnostic` that renders them, building a tree would link the diagnostic
/// library. Splitting the *name* of a problem from the *reporting* of one is
/// what keeps `ast` and `write` free of `error-report`.
///
/// The set is closed rather than a string because a consumer is expected to
/// match on it -- an editor deciding which quick fix to offer, a harness
/// deciding whether a corpus file is expected to fail. A string would make
/// every such decision a spelling comparison.
pub(all) enum ErrorKind {
/// The input ended in the middle of something.
UnexpectedEof
/// A string literal ran to the end of the line or the file.
UnterminatedString
/// A `/*` with no `*/`.
UnterminatedComment
/// A `url(` with no `)`.
UnterminatedUrl
/// A `url()` whose unquoted body contains a character that may not appear
/// there -- whitespace, a quote, a paren, or a control character.
BadUrl
/// A `)`, `]` or `}` with nothing open.
UnexpectedCloser(String)
/// A block opened and never closed.
UnclosedBlock(String)
/// A rule's prelude did not parse as a selector list.
BadSelector
/// A selector ran out where a compound was expected: a dangling combinator.
DanglingCombinator
/// `[` ... `]` that is not an attribute selector.
BadAttributeSelector
/// A pseudo-class whose argument list did not match its shape.
BadPseudoClass(String)
/// An `An+B` micro-syntax that did not parse.
BadAnB
/// A declaration with no `:`.
ExpectedColon
/// A declaration whose value is empty.
EmptyValue
/// `!important` somewhere other than the end of a value.
ImportantNotLast
/// A `!` that is not `!important`.
BadBang
/// A declaration that did not parse; the whole thing was skipped.
BadDeclaration
/// An at-rule that needed a block and did not have one, or the reverse.
BadAtRuleShape(String)
/// An at-rule name this library does not know. Tolerated: the rule is kept
/// with an unparsed prelude.
UnknownAtRule(String)
/// An at-rule prelude that did not parse as the shape its name requires.
BadAtRulePrelude(String)
/// A media query that did not parse.
BadMediaQuery
/// A `@supports` condition that did not parse.
BadSupportsCondition
/// `a and b or c` without parentheses. CSS requires them too.
MixedLogicalOps
/// A `@keyframes` selector that is neither `from`, `to`, nor a percentage.
BadKeyframeSelector
/// A declaration outside any rule.
DeclarationAtTopLevel
/// A rule where only declarations are allowed -- inside `@font-face`, say.
RuleInDeclarationContext
/// Anything else that could not be read. Carries what was expected.
Unexpected(String)
} derive(Eq, Debug)
///|
/// A stable identifier for this kind.
///
/// Stable is the whole point: it goes in `error[...]` headers, in JSON output
/// and in a harness's expectations, so it must not change when the prose does.
/// That is why it is written out rather than derived from the variant name --
/// renaming a variant is then a local edit, not a silent break of everything
/// downstream that matched on the string.
pub fn ErrorKind::code(self : ErrorKind) -> String {
let name = match self {
UnexpectedEof => "unexpected_eof"
UnterminatedString => "unterminated_string"
UnterminatedComment => "unterminated_comment"
UnterminatedUrl => "unterminated_url"
BadUrl => "bad_url"
UnexpectedCloser(_) => "unexpected_closer"
UnclosedBlock(_) => "unclosed_block"
BadSelector => "bad_selector"
DanglingCombinator => "dangling_combinator"
BadAttributeSelector => "bad_attribute_selector"
BadPseudoClass(_) => "bad_pseudo_class"
BadAnB => "bad_anb"
ExpectedColon => "expected_colon"
EmptyValue => "empty_value"
ImportantNotLast => "important_not_last"
BadBang => "bad_bang"
BadDeclaration => "bad_declaration"
BadAtRuleShape(_) => "bad_at_rule_shape"
UnknownAtRule(_) => "unknown_at_rule"
BadAtRulePrelude(_) => "bad_at_rule_prelude"
BadMediaQuery => "bad_media_query"
BadSupportsCondition => "bad_supports_condition"
MixedLogicalOps => "mixed_logical_ops"
BadKeyframeSelector => "bad_keyframe_selector"
DeclarationAtTopLevel => "declaration_at_top_level"
RuleInDeclarationContext => "rule_in_declaration_context"
Unexpected(_) => "unexpected"
}
"css::" + name
}
///|
/// Whether this kind is a hard error or something a tolerant parse may carry.
///
/// The distinction is what makes strict mode meaningful: strict fails on the
/// first `Error`, and an `UnknownAtRule` is deliberately not one -- CSS grows
/// new at-rules faster than any parser learns them, so refusing an unknown one
/// would make the library wrong every time the language moves.
pub fn ErrorKind::is_warning(self : ErrorKind) -> Bool {
match self {
UnknownAtRule(_) => true
_ => false
}
}