Skip to main content

css_parse/syntax/
bad_declaration.rs

1use super::prelude::*;
2use crate::{Result, syntax::ComponentValue};
3
4#[node]
5#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
7pub struct BadDeclaration<'a>(Vec<'a, ComponentValue<'a>>);
8
9// https://drafts.csswg.org/css-syntax-3/#consume-the-remnants-of-a-bad-declaration
10impl<'a> Parse<'a> for BadDeclaration<'a> {
11	fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
12	where
13		Iter: Iterator<Item = crate::Cursor> + Clone,
14	{
15		let mut values = Vec::new_in(p.alloc());
16		// To consume the remnants of a bad declaration from a token stream input, given a bool nested:
17		//
18		// Process input:
19		loop {
20			// <eof-token>
21			// <semicolon-token>
22			//
23			//     Discard a token from input, and return nothing.
24			if p.at_end() {
25				return Ok(Self(values));
26			}
27			let c = p.peek_n(1);
28			if <T![;]>::peek(p, c) {
29				values.push(p.parse::<ComponentValue>()?);
30				return Ok(Self(values));
31			}
32
33			// <}-token>
34			//
35			//     If nested is true, return nothing. Otherwise, discard a token.
36			if <T!['}']>::peek(p, c) {
37				if p.is(State::Nested) {
38					return Ok(Self(values));
39				} else {
40					p.parse::<T!['}']>()?;
41				}
42			}
43
44			// anything else
45			//
46			//     Consume a component value from input, and do nothing.
47			//
48			values.push(p.parse::<ComponentValue>()?);
49		}
50	}
51}
52
53impl<'a> ToSpan for BadDeclaration<'a> {
54	fn to_span(&self) -> Span {
55		self.0.to_span()
56	}
57}
58
59impl<'a> ToCursors for BadDeclaration<'a> {
60	fn to_cursors(&self, s: &mut impl CursorSink) {
61		for value in &self.0 {
62			ToCursors::to_cursors(value, s);
63		}
64	}
65}
66
67impl<'a> SemanticEq for BadDeclaration<'a> {
68	fn semantic_eq(&self, other: &Self) -> bool {
69		self.0.semantic_eq(&other.0)
70	}
71}
72
73impl<'a, M: crate::NodeMetadata> crate::NodeWithMetadata<M> for BadDeclaration<'a> {
74	fn metadata(&self) -> M {
75		M::default()
76	}
77}