1use std::fmt::{Display, Formatter};
2use std::hash::{Hash, Hasher};
3use std::str::FromStr;
4
5use nohash_hasher::IsEnabled;
6use strum_macros::{Display, EnumIter, EnumString, FromRepr, IntoStaticStr};
7
8#[derive(Debug, PartialEq, Eq, Clone)]
11pub struct Token<'a> {
12    pub span: (u32, u32), pub kind: TokenKind,  pub value: &'a str,   }
16
17#[derive(Debug, PartialEq, Eq, Clone, Copy, Display)]
20pub enum TokenKind {
21    Identifier(Identifier),       Boolean(bool),                Number,                       QuotationMark(QuotationMark), Literal,                      Operator(Operator),           Bracket(Bracket),             TemplateString(TemplateString), }
30
31#[derive(
34    Debug, PartialEq, Eq, Clone, Copy, Display, EnumString, IntoStaticStr,
35)]
36pub enum Identifier {
37    #[strum(serialize = "$")]
38    ContextReference, #[strum(serialize = "$root")]
40    RootReference, #[strum(serialize = "#")]
42    CallbackReference, #[strum(serialize = "null")]
44    Null, }
46
47#[derive(
50    Debug, PartialEq, Eq, Clone, Copy, Display, EnumString, IntoStaticStr,
51)]
52pub enum QuotationMark {
53    #[strum(serialize = "'")]
54    SingleQuote, #[strum(serialize = "\"")]
56    DoubleQuote, #[strum(serialize = "`")]
58    Backtick, }
60
61#[derive(Debug, PartialEq, Eq, Clone, Copy, EnumString, IntoStaticStr)]
64pub enum TemplateString {
65    #[strum(serialize = "${")]
66    ExpressionStart, #[strum(serialize = "}")]
68    ExpressionEnd, }
70
71impl Display for TemplateString {
72    fn fmt(
73        &self,
74        f: &mut Formatter<'_>,
75    ) -> std::fmt::Result {
76        match *self {
77            TemplateString::ExpressionStart => {
78                ::core::fmt::Display::fmt("${", f)
79            },
80            TemplateString::ExpressionEnd => ::core::fmt::Display::fmt("}}", f),
81        }
82    }
83}
84
85#[derive(Debug, PartialEq, Eq, Clone, Copy)]
88pub enum Operator {
89    Arithmetic(ArithmeticOperator), Logical(LogicalOperator),       Comparison(ComparisonOperator), Range,                          Comma,                          Slice,                          Dot,                            QuestionMark,                   }
98
99impl Display for Operator {
100    fn fmt(
101        &self,
102        f: &mut Formatter<'_>,
103    ) -> std::fmt::Result {
104        match self {
105            Operator::Arithmetic(a) => write!(f, "{a}"),
106            Operator::Logical(l) => write!(f, "{l}"),
107            Operator::Comparison(c) => write!(f, "{c}"),
108            Operator::Range => write!(f, ".."),
109            Operator::Comma => write!(f, ","),
110            Operator::Slice => write!(f, ":"),
111            Operator::Dot => write!(f, "."),
112            Operator::QuestionMark => write!(f, "?"),
113        }
114    }
115}
116
117impl FromStr for Operator {
118    type Err = strum::ParseError;
119
120    fn from_str(operator: &str) -> Result<Self, Self::Err> {
123        match operator {
124            ".." => Ok(Operator::Range),
125            "," => Ok(Operator::Comma),
126            ":" => Ok(Operator::Slice),
127            "." => Ok(Operator::Dot),
128            "?" => Ok(Operator::QuestionMark),
129            _ => ArithmeticOperator::try_from(operator)
130                .map(Operator::Arithmetic)
131                .or_else(|_| {
132                    LogicalOperator::try_from(operator).map(Operator::Logical)
133                })
134                .or_else(|_| {
135                    ComparisonOperator::try_from(operator)
136                        .map(Operator::Comparison)
137                }),
138        }
139    }
140}
141
142#[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumString)]
145pub enum ArithmeticOperator {
146    #[strum(serialize = "+")]
147    Add, #[strum(serialize = "-")]
149    Subtract, #[strum(serialize = "*")]
151    Multiply, #[strum(serialize = "/")]
153    Divide, #[strum(serialize = "%")]
155    Modulus, #[strum(serialize = "^")]
157    Power, }
159
160#[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumString)]
163pub enum LogicalOperator {
164    #[strum(serialize = "and")]
165    And, #[strum(serialize = "or")]
167    Or, #[strum(serialize = "not", serialize = "!")]
169    Not, #[strum(serialize = "??")]
171    NullishCoalescing, }
173
174#[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumString)]
177pub enum ComparisonOperator {
178    #[strum(serialize = "==")]
179    Equal, #[strum(serialize = "!=")]
181    NotEqual, #[strum(serialize = "<")]
183    LessThan, #[strum(serialize = ">")]
185    GreaterThan, #[strum(serialize = "<=")]
187    LessThanOrEqual, #[strum(serialize = ">=")]
189    GreaterThanOrEqual, #[strum(serialize = "in")]
191    In, #[strum(serialize = "not in")]
193    NotIn, }
195
196#[derive(
199    Debug,
200    PartialEq,
201    Eq,
202    Clone,
203    Copy,
204    EnumString,
205    IntoStaticStr,
206    EnumIter,
207    FromRepr,
208)]
209pub enum Bracket {
210    #[strum(serialize = "(")]
211    LeftParenthesis, #[strum(serialize = ")")]
213    RightParenthesis, #[strum(serialize = "[")]
215    LeftSquareBracket, #[strum(serialize = "]")]
217    RightSquareBracket, #[strum(serialize = "{")]
219    LeftCurlyBracket, #[strum(serialize = "}")]
221    RightCurlyBracket, }
223
224impl Display for Bracket {
225    fn fmt(
226        &self,
227        f: &mut Formatter<'_>,
228    ) -> std::fmt::Result {
229        match *self {
230            Bracket::LeftParenthesis => ::core::fmt::Display::fmt("(", f),
231            Bracket::RightParenthesis => ::core::fmt::Display::fmt(")", f),
232            Bracket::LeftSquareBracket => ::core::fmt::Display::fmt("[", f),
233            Bracket::RightSquareBracket => ::core::fmt::Display::fmt("]", f),
234            Bracket::LeftCurlyBracket => ::core::fmt::Display::fmt("{", f),
235            Bracket::RightCurlyBracket => ::core::fmt::Display::fmt("}}", f),
236        }
237    }
238}
239
240impl Operator {
241    pub fn variant(&self) -> u8 {
244        match &self {
245            Operator::Arithmetic(a) => match a {
246                ArithmeticOperator::Add => 1,
247                ArithmeticOperator::Subtract => 2,
248                ArithmeticOperator::Multiply => 3,
249                ArithmeticOperator::Divide => 4,
250                ArithmeticOperator::Modulus => 5,
251                ArithmeticOperator::Power => 6,
252            },
253            Operator::Logical(l) => match l {
254                LogicalOperator::And => 7,
255                LogicalOperator::Or => 8,
256                LogicalOperator::Not => 9,
257                LogicalOperator::NullishCoalescing => 10,
258            },
259            Operator::Comparison(c) => match c {
260                ComparisonOperator::Equal => 11,
261                ComparisonOperator::NotEqual => 12,
262                ComparisonOperator::LessThan => 13,
263                ComparisonOperator::GreaterThan => 14,
264                ComparisonOperator::LessThanOrEqual => 15,
265                ComparisonOperator::GreaterThanOrEqual => 16,
266                ComparisonOperator::In => 17,
267                ComparisonOperator::NotIn => 18,
268            },
269            Operator::Range => 19,
270            Operator::Comma => 20,
271            Operator::Slice => 21,
272            Operator::Dot => 22,
273            Operator::QuestionMark => 23,
274        }
275    }
276}
277
278impl Hash for Operator {
279    fn hash<H: Hasher>(
282        &self,
283        state: &mut H,
284    ) {
285        state.write_u8(self.variant());
286    }
287}
288
289impl IsEnabled for Operator {}