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