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}