Skip to main content

css_ast/rules/media/features/
hack.rs

1use crate::CssAtomSet;
2use css_parse::{Cursor, Diagnostic, Parse, Parser, Result as ParserResult, T};
3use csskit_derives::*;
4
5#[derive(Peek, ToCursors, ToSpan, SemanticEq, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
7#[derive(csskit_derives::NodeWithMetadata)]
8pub enum HackMediaFeature {
9	IEBackslashZero(T!['('], T![Ident], T![:], T![Dimension], #[semantic_eq(skip)] T![')']),
10}
11
12impl<'a> Parse<'a> for HackMediaFeature {
13	fn parse<I>(p: &mut Parser<'a, I>) -> ParserResult<Self>
14	where
15		I: Iterator<Item = Cursor> + Clone,
16	{
17		let open = p.parse::<T!['(']>()?;
18		let keyword = p.parse::<T![Ident]>()?;
19		if !p.equals_atom(keyword.into(), &CssAtomSet::MinWidth) {
20			Err(Diagnostic::new(keyword.into(), Diagnostic::expected_ident))?
21		}
22		let colon = p.parse::<T![:]>()?;
23		let dimension = p.parse::<T![Dimension]>()?;
24		let c: Cursor = dimension.into();
25		let str = p.to_source_cursor(c).source();
26		if str != "0\\0" {
27			Err(Diagnostic::new(c, Diagnostic::unexpected))?
28		}
29		let close = p.parse::<T![')']>()?;
30		Ok(Self::IEBackslashZero(open, keyword, colon, dimension, close))
31	}
32}
33
34#[cfg(test)]
35mod tests {
36	use super::*;
37	use crate::CssAtomSet;
38	use css_parse::assert_parse;
39
40	#[test]
41	fn test_writes() {
42		assert_parse!(CssAtomSet::ATOMS, HackMediaFeature, "(min-width:0\\0)");
43	}
44}