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, Assign, Semi, }
81
82impl Display for Operator {
83 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
84 match self {
85 Operator::Arithmetic(a) => write!(f, "{a}"),
86 Operator::Logical(l) => write!(f, "{l}"),
87 Operator::Comparison(c) => write!(f, "{c}"),
88 Operator::Range => write!(f, ".."),
89 Operator::Comma => write!(f, ","),
90 Operator::Slice => write!(f, ":"),
91 Operator::Dot => write!(f, "."),
92 Operator::QuestionMark => write!(f, "?"),
93 Operator::Assign => write!(f, "="),
94 Operator::Semi => write!(f, ";"),
95 }
96 }
97}
98
99impl FromStr for Operator {
100 type Err = strum::ParseError;
101
102 fn from_str(operator: &str) -> Result<Self, Self::Err> {
103 match operator {
104 ".." => Ok(Operator::Range),
105 "," => Ok(Operator::Comma),
106 ":" => Ok(Operator::Slice),
107 "." => Ok(Operator::Dot),
108 "?" => Ok(Operator::QuestionMark),
109 _ => ArithmeticOperator::try_from(operator)
110 .map(Operator::Arithmetic)
111 .or_else(|_| LogicalOperator::try_from(operator).map(Operator::Logical))
112 .or_else(|_| ComparisonOperator::try_from(operator).map(Operator::Comparison)),
113 }
114 }
115}
116
117#[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumString)]
118pub enum ArithmeticOperator {
119 #[strum(serialize = "+")]
120 Add,
121 #[strum(serialize = "-")]
122 Subtract,
123 #[strum(serialize = "*")]
124 Multiply,
125 #[strum(serialize = "/")]
126 Divide,
127 #[strum(serialize = "%")]
128 Modulus,
129 #[strum(serialize = "^")]
130 Power,
131}
132
133#[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumString)]
134pub enum LogicalOperator {
135 #[strum(serialize = "and")]
136 And,
137 #[strum(serialize = "or")]
138 Or,
139 #[strum(serialize = "not", serialize = "!")]
140 Not,
141 #[strum(serialize = "??")]
142 NullishCoalescing,
143}
144
145#[derive(Debug, PartialEq, Eq, Clone, Copy, Display, EnumString)]
146pub enum ComparisonOperator {
147 #[strum(serialize = "==")]
148 Equal,
149 #[strum(serialize = "!=")]
150 NotEqual,
151 #[strum(serialize = "<")]
152 LessThan,
153 #[strum(serialize = ">")]
154 GreaterThan,
155 #[strum(serialize = "<=")]
156 LessThanOrEqual,
157 #[strum(serialize = ">=")]
158 GreaterThanOrEqual,
159 #[strum(serialize = "in")]
160 In,
161 #[strum(serialize = "not in")]
162 NotIn,
163}
164
165#[derive(Debug, PartialEq, Eq, Clone, Copy, EnumString, IntoStaticStr, EnumIter, FromRepr)]
166pub enum Bracket {
167 #[strum(serialize = "(")]
168 LeftParenthesis,
169 #[strum(serialize = ")")]
170 RightParenthesis,
171 #[strum(serialize = "[")]
172 LeftSquareBracket,
173 #[strum(serialize = "]")]
174 RightSquareBracket,
175 #[strum(serialize = "{")]
176 LeftCurlyBracket,
177 #[strum(serialize = "}")]
178 RightCurlyBracket,
179}
180
181impl Display for Bracket {
182 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
183 match *self {
184 Bracket::LeftParenthesis => ::core::fmt::Display::fmt("(", f),
185 Bracket::RightParenthesis => ::core::fmt::Display::fmt(")", f),
186 Bracket::LeftSquareBracket => ::core::fmt::Display::fmt("[", f),
187 Bracket::RightSquareBracket => ::core::fmt::Display::fmt("]", f),
188 Bracket::LeftCurlyBracket => ::core::fmt::Display::fmt("{", f),
189 Bracket::RightCurlyBracket => ::core::fmt::Display::fmt("}}", f),
190 }
191 }
192}
193
194impl Operator {
195 pub fn variant(&self) -> u8 {
196 match &self {
197 Operator::Arithmetic(a) => match a {
198 ArithmeticOperator::Add => 1,
199 ArithmeticOperator::Subtract => 2,
200 ArithmeticOperator::Multiply => 3,
201 ArithmeticOperator::Divide => 4,
202 ArithmeticOperator::Modulus => 5,
203 ArithmeticOperator::Power => 6,
204 },
205 Operator::Logical(l) => match l {
206 LogicalOperator::And => 7,
207 LogicalOperator::Or => 8,
208 LogicalOperator::Not => 9,
209 LogicalOperator::NullishCoalescing => 10,
210 },
211 Operator::Comparison(c) => match c {
212 ComparisonOperator::Equal => 11,
213 ComparisonOperator::NotEqual => 12,
214 ComparisonOperator::LessThan => 13,
215 ComparisonOperator::GreaterThan => 14,
216 ComparisonOperator::LessThanOrEqual => 15,
217 ComparisonOperator::GreaterThanOrEqual => 16,
218 ComparisonOperator::In => 17,
219 ComparisonOperator::NotIn => 18,
220 },
221 Operator::Range => 19,
222 Operator::Comma => 20,
223 Operator::Slice => 21,
224 Operator::Dot => 22,
225 Operator::QuestionMark => 23,
226 Operator::Assign => 24,
227 Operator::Semi => 25,
228 }
229 }
230}
231
232impl Hash for Operator {
233 fn hash<H: Hasher>(&self, state: &mut H) {
234 state.write_u8(self.variant());
235 }
236}
237
238impl IsEnabled for Operator {}