jomini/text/operator.rs
1use std::fmt::Display;
2
3/// An operator token
4///
5/// This enum contains only non-equal operators due to their rarity. Including
6/// an equals operator would increase the size of the token list by up to 50%.
7#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
8pub enum Operator {
9 /// A `<` token
10 LessThan,
11
12 /// A `<=` token
13 LessThanEqual,
14
15 /// A `>` token
16 GreaterThan,
17
18 /// A `>=` token
19 GreaterThanEqual,
20
21 /// A `!=` token
22 NotEqual,
23
24 /// A `==` token
25 Exact,
26
27 /// A `=` token
28 Equal,
29
30 /// A `?=` token
31 Exists,
32}
33
34impl Display for Operator {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 f.write_str(self.symbol())
37 }
38}
39
40impl Operator {
41 /// Returns the name of the operator using only letters
42 ///
43 /// ```
44 /// use jomini::text::Operator;
45 /// assert_eq!(Operator::LessThan.symbol(), "<");
46 /// assert_eq!(Operator::LessThanEqual.symbol(), "<=");
47 /// assert_eq!(Operator::GreaterThan.symbol(), ">");
48 /// assert_eq!(Operator::GreaterThanEqual.symbol(), ">=");
49 /// assert_eq!(Operator::Exact.symbol(), "==");
50 /// assert_eq!(Operator::NotEqual.symbol(), "!=");
51 /// assert_eq!(Operator::Equal.symbol(), "=");
52 /// assert_eq!(Operator::Exists.symbol(), "?=");
53 /// ```
54 pub fn symbol(&self) -> &'static str {
55 match self {
56 Operator::LessThan => "<",
57 Operator::LessThanEqual => "<=",
58 Operator::GreaterThan => ">",
59 Operator::GreaterThanEqual => ">=",
60 Operator::Exact => "==",
61 Operator::Equal => "=",
62 Operator::NotEqual => "!=",
63 Operator::Exists => "?=",
64 }
65 }
66
67 /// Returns the name of the operator using only letters
68 ///
69 /// ```
70 /// use jomini::text::Operator;
71 /// assert_eq!(Operator::LessThan.name(), "LESS_THAN");
72 /// assert_eq!(Operator::LessThanEqual.name(), "LESS_THAN_EQUAL");
73 /// assert_eq!(Operator::GreaterThan.name(), "GREATER_THAN");
74 /// assert_eq!(Operator::GreaterThanEqual.name(), "GREATER_THAN_EQUAL");
75 /// assert_eq!(Operator::Exact.name(), "EXACT");
76 /// assert_eq!(Operator::NotEqual.name(), "NOT_EQUAL");
77 /// assert_eq!(Operator::Equal.name(), "EQUAL");
78 /// assert_eq!(Operator::Exists.name(), "EXISTS");
79 /// ```
80 pub fn name(&self) -> &'static str {
81 match self {
82 Operator::LessThan => "LESS_THAN",
83 Operator::LessThanEqual => "LESS_THAN_EQUAL",
84 Operator::GreaterThan => "GREATER_THAN",
85 Operator::GreaterThanEqual => "GREATER_THAN_EQUAL",
86 Operator::Exact => "EXACT",
87 Operator::Equal => "EQUAL",
88 Operator::NotEqual => "NOT_EQUAL",
89 Operator::Exists => "EXISTS",
90 }
91 }
92}
93
94#[cfg(feature = "serde")]
95impl<'de> serde::Deserialize<'de> for Operator {
96 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
97 where
98 D: serde::Deserializer<'de>,
99 {
100 struct OperatorVisitor;
101
102 impl<'de> serde::de::Visitor<'de> for OperatorVisitor {
103 type Value = Operator;
104
105 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
106 formatter.write_str("an operator")
107 }
108
109 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
110 where
111 E: serde::de::Error,
112 {
113 match v {
114 "<" => Ok(Operator::LessThan),
115 "<=" => Ok(Operator::LessThanEqual),
116 ">" => Ok(Operator::GreaterThan),
117 ">=" => Ok(Operator::GreaterThanEqual),
118 "==" => Ok(Operator::Exact),
119 "=" => Ok(Operator::Equal),
120 "!=" => Ok(Operator::NotEqual),
121 "?=" => Ok(Operator::Exists),
122 _ => Err(E::custom("did not receive a known operator")),
123 }
124 }
125 }
126 deserializer.deserialize_str(OperatorVisitor)
127 }
128}