1use serde::Serialize;
2
3use crate::lexer::{ArithmeticOperator, ComparisonOperator, LogicalOperator, Operator};
4
5#[derive(Debug, Clone, Serialize)]
6#[serde(rename_all = "camelCase")]
7pub struct NlToken {
8 pub token: NlTokenKind,
9 pub span: (u32, u32),
10 #[serde(skip_serializing_if = "Option::is_none")]
11 pub hint: Option<EditHint>,
12}
13
14#[derive(Debug, Clone, PartialEq, Serialize)]
15#[serde(tag = "t", rename_all = "camelCase")]
16pub enum NlTokenKind {
17 GroupOpen,
18 GroupClose,
19 ListOpen,
20 ListClose,
21 Comma,
22 EnumList {
23 selected: Vec<Box<str>>,
24 },
25
26 Context,
27 Root,
28 Null,
29
30 Field {
31 path: Vec<Box<str>>,
32 ty: TypeTag,
33 },
34 Element {
35 #[serde(skip_serializing_if = "Option::is_none")]
36 alias: Option<Box<str>>,
37 },
38
39 Number {
40 value: Box<str>,
41 },
42 Str {
43 value: Box<str>,
44 },
45 Bool {
46 value: bool,
47 },
48
49 Op {
50 sym: OpSym,
51 implied: bool,
52 between: bool,
53 },
54 Word {
55 sym: WordSym,
56 },
57 Assign,
58 StmtEnd,
59 Func {
60 sym: Box<str>,
61 closure: bool,
62 },
63 Method {
64 sym: Box<str>,
65 },
66
67 TemplateOpen,
68 TemplateText {
69 value: Box<str>,
70 },
71 TemplateClose,
72
73 IntervalOpen {
74 inclusive: bool,
75 },
76 IntervalClose {
77 inclusive: bool,
78 },
79
80 Code {
81 source: Box<str>,
82 },
83}
84
85#[derive(Debug, Clone, PartialEq, Serialize)]
86#[serde(tag = "t", rename_all = "camelCase")]
87pub enum TypeTag {
88 Number,
89 String,
90 Bool,
91 Date,
92 Interval,
93 Object,
94 Null,
95 Unknown,
96 Enum { index: u32 },
97 Array { items: Box<TypeTag> },
98}
99
100#[derive(Debug, Clone, PartialEq, Serialize)]
101#[serde(tag = "kind", rename_all = "camelCase")]
102pub enum EditHint {
103 DatePicker,
104 Select {
105 options: u32,
106 },
107 MultiSelect {
108 options: u32,
109 },
110 OpSelect {
111 options: Vec<OpChoice>,
112 },
113 QuantSelect {
114 options: Vec<OpSym>,
115 subject: Box<str>,
116 list: Box<str>,
117 },
118 FuncSelect {
119 options: Vec<Box<str>>,
120 },
121}
122
123#[derive(Debug, Clone, PartialEq, Serialize)]
124#[serde(rename_all = "camelCase")]
125pub struct OpChoice {
126 pub sym: OpSym,
127 pub source: &'static str,
128}
129
130impl From<OpSym> for OpChoice {
131 fn from(sym: OpSym) -> Self {
132 Self {
133 sym,
134 source: sym.source(),
135 }
136 }
137}
138
139#[derive(Debug, Clone, PartialEq, Serialize)]
140#[serde(rename_all = "camelCase")]
141pub struct EnumOption {
142 pub label: String,
143 #[serde(skip_serializing_if = "Option::is_none")]
144 pub source: Option<String>,
145}
146
147#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
148#[serde(rename_all = "camelCase")]
149pub enum OpSym {
150 Gt,
151 Gte,
152 Lt,
153 Lte,
154 Eq,
155 Ne,
156 In,
157 NotIn,
158 Contains,
159 NotContains,
160 ContainsAny,
161 ContainsAll,
162 ContainsNone,
163 ContainsOnly,
164 Add,
165 Sub,
166 Mul,
167 Div,
168 Mod,
169 Pow,
170 And,
171 Or,
172 Not,
173 Coalesce,
174}
175
176impl OpSym {
177 pub fn source(&self) -> &'static str {
178 match self {
179 OpSym::Gt => ">",
180 OpSym::Gte => ">=",
181 OpSym::Lt => "<",
182 OpSym::Lte => "<=",
183 OpSym::Eq => "==",
184 OpSym::Ne => "!=",
185 OpSym::In => "in",
186 OpSym::NotIn => "not in",
187 OpSym::Contains => "in",
188 OpSym::NotContains => "not in",
189 OpSym::ContainsAny => "some",
190 OpSym::ContainsAll => "all",
191 OpSym::ContainsNone => "none",
192 OpSym::ContainsOnly => "all",
193 OpSym::Add => "+",
194 OpSym::Sub => "-",
195 OpSym::Mul => "*",
196 OpSym::Div => "/",
197 OpSym::Mod => "%",
198 OpSym::Pow => "^",
199 OpSym::And => "and",
200 OpSym::Or => "or",
201 OpSym::Not => "not",
202 OpSym::Coalesce => "??",
203 }
204 }
205
206 pub(crate) fn from_operator(operator: Operator) -> Option<Self> {
207 match operator {
208 Operator::Arithmetic(a) => Some(match a {
209 ArithmeticOperator::Add => OpSym::Add,
210 ArithmeticOperator::Subtract => OpSym::Sub,
211 ArithmeticOperator::Multiply => OpSym::Mul,
212 ArithmeticOperator::Divide => OpSym::Div,
213 ArithmeticOperator::Modulus => OpSym::Mod,
214 ArithmeticOperator::Power => OpSym::Pow,
215 }),
216 Operator::Logical(l) => Some(match l {
217 LogicalOperator::And => OpSym::And,
218 LogicalOperator::Or => OpSym::Or,
219 LogicalOperator::Not => OpSym::Not,
220 LogicalOperator::NullishCoalescing => OpSym::Coalesce,
221 }),
222 Operator::Comparison(c) => Some(match c {
223 ComparisonOperator::Equal => OpSym::Eq,
224 ComparisonOperator::NotEqual => OpSym::Ne,
225 ComparisonOperator::LessThan => OpSym::Lt,
226 ComparisonOperator::GreaterThan => OpSym::Gt,
227 ComparisonOperator::LessThanOrEqual => OpSym::Lte,
228 ComparisonOperator::GreaterThanOrEqual => OpSym::Gte,
229 ComparisonOperator::In => OpSym::In,
230 ComparisonOperator::NotIn => OpSym::NotIn,
231 }),
232 _ => None,
233 }
234 }
235}
236
237#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
238#[serde(rename_all = "camelCase")]
239pub enum WordSym {
240 If,
241 Then,
242 Otherwise,
243 In,
244 Where,
245 Has,
246 RangeAnd,
247}