1use std::fmt;
2
3use crate::{Diagnostic, Parse, Parser, Peek, Result, SemanticEq, T, ToCursors};
4use css_lexer::{Span, ToSpan};
5
6#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
23pub enum Comparison {
24 LessThan(T![<]),
25 GreaterThan(T![>]),
26 GreaterThanEqual(T![>=]),
27 LessThanEqual(T![<=]),
28 Equal(T![=]),
29}
30
31impl<'a> Parse<'a> for Comparison {
32 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Comparison>
33 where
34 I: Iterator<Item = crate::Cursor> + Clone,
35 {
36 let c = p.peek_n(1);
37 match c.token().char() {
38 Some('=') => p.parse::<T![=]>().map(Comparison::Equal),
39 Some('>') => {
40 if <T![>=]>::peek(p, c) {
41 p.parse::<T![>=]>().map(Comparison::GreaterThanEqual)
42 } else {
43 p.parse::<T![>]>().map(Comparison::GreaterThan)
44 }
45 }
46 Some('<') => {
47 if <T![<=]>::peek(p, c) {
48 p.parse::<T![<=]>().map(Comparison::LessThanEqual)
49 } else {
50 p.parse::<T![<]>().map(Comparison::LessThan)
51 }
52 }
53 Some(_) => Err(Diagnostic::new(p.next(), Diagnostic::unexpected_delim))?,
54 _ => Err(Diagnostic::new(p.next(), Diagnostic::unexpected))?,
55 }
56 }
57}
58
59impl ToCursors for Comparison {
60 fn to_cursors(&self, s: &mut impl crate::CursorSink) {
61 match self {
62 Self::LessThan(c) => ToCursors::to_cursors(c, s),
63 Self::GreaterThan(c) => ToCursors::to_cursors(c, s),
64 Self::GreaterThanEqual(c) => ToCursors::to_cursors(c, s),
65 Self::LessThanEqual(c) => ToCursors::to_cursors(c, s),
66 Self::Equal(c) => ToCursors::to_cursors(c, s),
67 }
68 }
69}
70
71impl fmt::Display for Comparison {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 f.write_str(match self {
74 Self::LessThan(_) => "<",
75 Self::GreaterThan(_) => ">",
76 Self::GreaterThanEqual(_) => ">=",
77 Self::LessThanEqual(_) => "<=",
78 Self::Equal(_) => "=",
79 })
80 }
81}
82
83impl ToSpan for Comparison {
84 fn to_span(&self) -> Span {
85 match self {
86 Self::LessThan(c) => c.to_span(),
87 Self::GreaterThan(c) => c.to_span(),
88 Self::GreaterThanEqual(c) => c.to_span(),
89 Self::LessThanEqual(c) => c.to_span(),
90 Self::Equal(c) => c.to_span(),
91 }
92 }
93}
94
95impl SemanticEq for Comparison {
96 fn semantic_eq(&self, other: &Self) -> bool {
97 match (self, other) {
98 (Self::LessThan(a), Self::LessThan(b)) => a.semantic_eq(b),
99 (Self::GreaterThan(a), Self::GreaterThan(b)) => a.semantic_eq(b),
100 (Self::GreaterThanEqual(a), Self::GreaterThanEqual(b)) => a.semantic_eq(b),
101 (Self::LessThanEqual(a), Self::LessThanEqual(b)) => a.semantic_eq(b),
102 (Self::Equal(a), Self::Equal(b)) => a.semantic_eq(b),
103 _ => false,
104 }
105 }
106}