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)]
10pub struct Token<'a> {
11 pub span: (u32, u32),
12 pub kind: TokenKind,
13 pub value: &'a str,
14}
15
16#[derive(Debug, PartialEq, Eq, Clone, Copy, Display)]
18pub enum TokenKind {
19 Identifier(Identifier),
20 Boolean(bool),
21 Number,
22 QuotationMark(QuotationMark),
23 Literal,
24 Operator(Operator),
25 Bracket(Bracket),
26 TemplateString(TemplateString),
27}
28
29#[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumString, IntoStaticStr)]
30pub enum Identifier {
31 #[strum(serialize = "$")]
32 ContextReference,
33 #[strum(serialize = "$root")]
34 RootReference,
35 #[strum(serialize = "#")]
36 CallbackReference,
37 #[strum(serialize = "null")]
38 Null,
39}
40
41#[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumString, IntoStaticStr)]
42pub enum QuotationMark {
43 #[strum(serialize = "'")]
44 SingleQuote,
45 #[strum(serialize = "\"")]
46 DoubleQuote,
47 #[strum(serialize = "`")]
48 Backtick,
49}
50
51#[derive(Debug, PartialEq, Eq, Clone, Copy, EnumString, IntoStaticStr)]
52pub enum TemplateString {
53 #[strum(serialize = "${")]
54 ExpressionStart,
55 #[strum(serialize = "}")]
56 ExpressionEnd,
57}
58
59impl Display for TemplateString {
60 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
61 match *self {
62 TemplateString::ExpressionStart => ::core::fmt::Display::fmt("${", f),
63 TemplateString::ExpressionEnd => ::core::fmt::Display::fmt("}}", f),
64 }
65 }
66}
67
68#[derive(Debug, PartialEq, Eq, Clone, Copy)]
69pub enum Operator {
70 Arithmetic(ArithmeticOperator),
71 Logical(LogicalOperator),
72 Comparison(ComparisonOperator),
73 Range, Comma, Slice, Dot, QuestionMark, }
79
80impl Display for Operator {
81 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
82 match self {
83 Operator::Arithmetic(a) => write!(f, "{a}"),
84 Operator::Logical(l) => write!(f, "{l}"),
85 Operator::Comparison(c) => write!(f, "{c}"),
86 Operator::Range => write!(f, ".."),
87 Operator::Comma => write!(f, ","),
88 Operator::Slice => write!(f, ":"),
89 Operator::Dot => write!(f, "."),
90 Operator::QuestionMark => write!(f, "?"),
91 }
92 }
93}
94
95impl FromStr for Operator {
96 type Err = strum::ParseError;
97
98 fn from_str(operator: &str) -> Result<Self, Self::Err> {
99 match operator {
100 ".." => Ok(Operator::Range),
101 "," => Ok(Operator::Comma),
102 ":" => Ok(Operator::Slice),
103 "." => Ok(Operator::Dot),
104 "?" => Ok(Operator::QuestionMark),
105 _ => ArithmeticOperator::try_from(operator)
106 .map(Operator::Arithmetic)
107 .or_else(|_| LogicalOperator::try_from(operator).map(Operator::Logical))
108 .or_else(|_| ComparisonOperator::try_from(operator).map(Operator::Comparison)),
109 }
110 }
111}
112
113#[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumString)]
114pub enum ArithmeticOperator {
115 #[strum(serialize = "+")]
116 Add,
117 #[strum(serialize = "-")]
118 Subtract,
119 #[strum(serialize = "*")]
120 Multiply,
121 #[strum(serialize = "/")]
122 Divide,
123 #[strum(serialize = "%")]
124 Modulus,
125 #[strum(serialize = "^")]
126 Power,
127}
128
129#[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumString)]
130pub enum LogicalOperator {
131 #[strum(serialize = "and")]
132 And,
133 #[strum(serialize = "or")]
134 Or,
135 #[strum(serialize = "not", serialize = "!")]
136 Not,
137 #[strum(serialize = "??")]
138 NullishCoalescing,
139}
140
141#[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumString)]
142pub enum ComparisonOperator {
143 #[strum(serialize = "==")]
144 Equal,
145 #[strum(serialize = "!=")]
146 NotEqual,
147 #[strum(serialize = "<")]
148 LessThan,
149 #[strum(serialize = ">")]
150 GreaterThan,
151 #[strum(serialize = "<=")]
152 LessThanOrEqual,
153 #[strum(serialize = ">=")]
154 GreaterThanOrEqual,
155 #[strum(serialize = "in")]
156 In,
157 #[strum(serialize = "not in")]
158 NotIn,
159}
160
161#[derive(Debug, PartialEq, Eq, Clone, Copy, EnumString, IntoStaticStr, EnumIter, FromRepr)]
162pub enum Bracket {
163 #[strum(serialize = "(")]
164 LeftParenthesis,
165 #[strum(serialize = ")")]
166 RightParenthesis,
167 #[strum(serialize = "[")]
168 LeftSquareBracket,
169 #[strum(serialize = "]")]
170 RightSquareBracket,
171 #[strum(serialize = "{")]
172 LeftCurlyBracket,
173 #[strum(serialize = "}")]
174 RightCurlyBracket,
175}
176
177impl Display for Bracket {
178 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
179 match *self {
180 Bracket::LeftParenthesis => ::core::fmt::Display::fmt("(", f),
181 Bracket::RightParenthesis => ::core::fmt::Display::fmt(")", f),
182 Bracket::LeftSquareBracket => ::core::fmt::Display::fmt("[", f),
183 Bracket::RightSquareBracket => ::core::fmt::Display::fmt("]", f),
184 Bracket::LeftCurlyBracket => ::core::fmt::Display::fmt("{", f),
185 Bracket::RightCurlyBracket => ::core::fmt::Display::fmt("}}", f),
186 }
187 }
188}
189
190impl Operator {
191 pub fn variant(&self) -> u8 {
192 match &self {
193 Operator::Arithmetic(a) => match a {
194 ArithmeticOperator::Add => 1,
195 ArithmeticOperator::Subtract => 2,
196 ArithmeticOperator::Multiply => 3,
197 ArithmeticOperator::Divide => 4,
198 ArithmeticOperator::Modulus => 5,
199 ArithmeticOperator::Power => 6,
200 },
201 Operator::Logical(l) => match l {
202 LogicalOperator::And => 7,
203 LogicalOperator::Or => 8,
204 LogicalOperator::Not => 9,
205 LogicalOperator::NullishCoalescing => 10,
206 },
207 Operator::Comparison(c) => match c {
208 ComparisonOperator::Equal => 11,
209 ComparisonOperator::NotEqual => 12,
210 ComparisonOperator::LessThan => 13,
211 ComparisonOperator::GreaterThan => 14,
212 ComparisonOperator::LessThanOrEqual => 15,
213 ComparisonOperator::GreaterThanOrEqual => 16,
214 ComparisonOperator::In => 17,
215 ComparisonOperator::NotIn => 18,
216 },
217 Operator::Range => 19,
218 Operator::Comma => 20,
219 Operator::Slice => 21,
220 Operator::Dot => 22,
221 Operator::QuestionMark => 23,
222 }
223 }
224}
225
226impl Hash for Operator {
227 fn hash<H: Hasher>(&self, state: &mut H) {
228 state.write_u8(self.variant());
229 }
230}
231
232impl IsEnabled for Operator {}