Skip to main content

css_parse/syntax/
declaration_or_bad.rs

1use super::prelude::*;
2use crate::{BadDeclaration, Declaration};
3
4/// Either a valid declaration or a bad declaration consumed for error recovery.
5///
6/// Per the CSS spec, when parsing fails for both a declaration and a rule,
7/// we consume the remnants as a bad declaration to maintain error recovery.
8#[node]
9#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
11pub enum DeclarationOrBad<'a, D, M>
12where
13	D: DeclarationValue<'a, M>,
14	M: NodeMetadata,
15{
16	Declaration(Declaration<'a, D, M>),
17	Bad(BadDeclaration<'a>),
18}
19
20impl<'a, D, M> ToCursors for DeclarationOrBad<'a, D, M>
21where
22	D: DeclarationValue<'a, M> + ToCursors,
23	M: NodeMetadata,
24{
25	fn to_cursors(&self, s: &mut impl CursorSink) {
26		match self {
27			Self::Declaration(d) => d.to_cursors(s),
28			Self::Bad(b) => b.to_cursors(s),
29		}
30	}
31}
32
33impl<'a, D, M> ToSpan for DeclarationOrBad<'a, D, M>
34where
35	D: DeclarationValue<'a, M> + ToSpan,
36	M: NodeMetadata,
37{
38	fn to_span(&self) -> Span {
39		match self {
40			Self::Declaration(d) => d.to_span(),
41			Self::Bad(b) => b.to_span(),
42		}
43	}
44}
45
46impl<'a, D, M> SemanticEq for DeclarationOrBad<'a, D, M>
47where
48	D: DeclarationValue<'a, M>,
49	M: NodeMetadata,
50{
51	fn semantic_eq(&self, other: &Self, source_text: &str) -> bool {
52		match (self, other) {
53			(Self::Declaration(a), Self::Declaration(b)) => a.semantic_eq(b, source_text),
54			(Self::Bad(a), Self::Bad(b)) => a.semantic_eq(b, source_text),
55			_ => false,
56		}
57	}
58}
59
60impl<'a, D, M> NodeWithMetadata<M> for DeclarationOrBad<'a, D, M>
61where
62	D: DeclarationValue<'a, M>,
63	M: NodeMetadata,
64{
65	fn metadata(&self) -> M {
66		match self {
67			Self::Declaration(d) => d.metadata(),
68			Self::Bad(b) => b.metadata(),
69		}
70	}
71}