css_parse/syntax/
attribute_operator.rs1use super::prelude::*;
2
3#[node]
7#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
9pub enum AttributeOperator {
10 Exact(T![=]),
11 SpaceList(T![~=]),
12 LangPrefix(T![|=]),
13 Prefix(T![^=]),
14 Suffix(T!["$="]),
15 Contains(T![*=]),
16}
17
18impl<M: NodeMetadata> NodeWithMetadata<M> for AttributeOperator {
19 fn metadata(&self) -> M {
20 M::default()
21 }
22}
23
24impl<'a> Peek<'a> for AttributeOperator {
25 const PEEK_KINDSET: KindSet = KindSet::new(&[Kind::Delim]);
26}
27
28impl<'a> Parse<'a> for AttributeOperator {
29 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
30 where
31 I: Iterator<Item = Cursor> + Clone,
32 {
33 if p.peek::<T![~=]>() {
34 p.parse::<T![~=]>().map(Self::SpaceList)
35 } else if p.peek::<T![|=]>() {
36 p.parse::<T![|=]>().map(Self::LangPrefix)
37 } else if p.peek::<T![^=]>() {
38 p.parse::<T![^=]>().map(Self::Prefix)
39 } else if p.peek::<T!["$="]>() {
40 p.parse::<T!["$="]>().map(Self::Suffix)
41 } else if p.peek::<T![*=]>() {
42 p.parse::<T![*=]>().map(Self::Contains)
43 } else {
44 p.parse::<T![=]>().map(Self::Exact)
45 }
46 }
47}
48
49impl ToCursors for AttributeOperator {
50 fn to_cursors(&self, s: &mut impl CursorSink) {
51 match self {
52 Self::Exact(t) => t.to_cursors(s),
53 Self::SpaceList(t) => t.to_cursors(s),
54 Self::LangPrefix(t) => t.to_cursors(s),
55 Self::Prefix(t) => t.to_cursors(s),
56 Self::Suffix(t) => t.to_cursors(s),
57 Self::Contains(t) => t.to_cursors(s),
58 }
59 }
60}
61
62impl ToSpan for AttributeOperator {
63 fn to_span(&self) -> Span {
64 match self {
65 Self::Exact(t) => t.to_span(),
66 Self::SpaceList(t) => t.to_span(),
67 Self::LangPrefix(t) => t.to_span(),
68 Self::Prefix(t) => t.to_span(),
69 Self::Suffix(t) => t.to_span(),
70 Self::Contains(t) => t.to_span(),
71 }
72 }
73}
74
75impl SemanticEq for AttributeOperator {
76 fn semantic_eq(&self, other: &Self, _source_text: &str) -> bool {
77 std::mem::discriminant(self) == std::mem::discriminant(other)
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84 use crate::{EmptyAtomSet, assert_parse};
85
86 #[test]
87 fn test_writes() {
88 assert_parse!(EmptyAtomSet::ATOMS, AttributeOperator, "=");
89 assert_parse!(EmptyAtomSet::ATOMS, AttributeOperator, "~=");
90 assert_parse!(EmptyAtomSet::ATOMS, AttributeOperator, "|=");
91 assert_parse!(EmptyAtomSet::ATOMS, AttributeOperator, "^=");
92 assert_parse!(EmptyAtomSet::ATOMS, AttributeOperator, "$=");
93 assert_parse!(EmptyAtomSet::ATOMS, AttributeOperator, "*=");
94 }
95}