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 {}