1use crate::lexer_constants::*;
2use std::collections::LinkedList;
3use std::fmt::Debug;
4use std::num::ParseIntError;
5use std::ops::{Deref, DerefMut};
6
7#[derive(Debug, Eq, PartialEq)]
8pub enum LexerError {
9 EndOfQuery {
10 expected: String,
11 char_pointer: usize,
12 lex: String,
13 },
14 FailedToParseInt(ParseIntError),
15 UnexpectedCharacter {
16 expected: String,
17 found: String,
18 char_pointer: usize,
19 lex: String,
20 },
21}
22
23impl From<ParseIntError> for LexerError {
24 fn from(e: ParseIntError) -> Self {
25 Self::FailedToParseInt(e)
26 }
27}
28
29pub type LexResult<T> = Result<T, LexerError>;
30
31#[derive(Debug, Eq, PartialEq, Clone)]
32pub enum GenericObjectIndex {
33 Wildcard,
34 Slice(LinkedList<Slicer>),
35}
36
37#[derive(Debug, Eq, PartialEq, Clone)]
38pub enum Slicer {
39 Index(usize),
40 Slice(usize, usize),
41 Ident(String),
42}
43
44#[derive(Debug, Eq, PartialEq, Clone)]
45pub enum LexOperator {
46 Identifier(String),
47 Pipe(LinkedList<LexOperator>),
48 Generic(GenericObjectIndex),
49}
50
51#[derive(Debug, Eq, PartialEq, Clone)]
52pub struct LexicalOperations(LinkedList<LexOperator>);
53
54impl From<LinkedList<LexOperator>> for LexicalOperations {
55 fn from(v: LinkedList<LexOperator>) -> Self {
56 Self(v)
57 }
58}
59
60impl Deref for LexicalOperations {
61 type Target = LinkedList<LexOperator>;
62
63 fn deref(&self) -> &Self::Target {
64 &self.0
65 }
66}
67
68impl DerefMut for LexicalOperations {
69 fn deref_mut(&mut self) -> &mut Self::Target {
70 &mut self.0
71 }
72}
73
74impl TryInto<LexicalOperations> for &str {
75 type Error = String;
76
77 fn try_into(self) -> Result<LexicalOperations, String> {
78 compile(self).map_err(|e| format!("{:?}", e))
79 }
80}
81
82pub fn compile(s: &str) -> LexResult<LexicalOperations> {
83 let mut lexer_vec = s.chars().into_iter().collect::<Vec<char>>();
84 lexer_vec.reverse();
85 generic_compiler(
86 &mut lexer_vec,
87 &mut Default::default(),
88 Default::default(),
89 false,
90 Default::default(),
91 )
92 .map(LexicalOperations::from)
93}
94
95pub fn generic_compiler(
96 lexer_vec: &mut Vec<char>,
97 mut operator: &mut LinkedList<LexOperator>,
98 mut collect: String,
99 mut escape: bool,
100 mut char_pointer: usize,
101) -> LexResult<LinkedList<LexOperator>> {
102 let char = lexer_vec.pop();
103 if let Some(c) = char {
104 char_pointer = char_pointer + 1;
105 if !escape {
106 match c {
107 LEX_ESCAPE => {
108 escape = true;
109 }
110 LEX_IDENTIFIER => {
111 if !collect.is_empty() {
112 operator.push_back(LexOperator::Identifier(collect));
113 }
114 collect = Default::default();
115 }
116 LEX_GENERIC_START => {
117 if !collect.is_empty() {
118 operator.push_back(LexOperator::Identifier(collect));
119 collect = Default::default();
120 }
121 let v = generic_object_index(
122 lexer_vec,
123 Default::default(),
124 LinkedList::new(),
125 None,
126 false,
127 char_pointer,
128 )?;
129 operator.push_back(LexOperator::Generic(v));
130 }
131 _ => {
132 if c != LEX_ROUGE_WIDESPACE {
133 collect.push(c)
134 }
135 }
136 }
137 } else {
138 collect.push(c);
139 escape = false;
140 }
141 generic_compiler(lexer_vec, operator, collect, escape, char_pointer)
142 } else {
143 Ok(operator.clone())
144 }
145}
146
147fn generic_object_index(
148 lexer_vec: &mut Vec<char>,
149 mut collect: String,
150 mut slicer: LinkedList<Slicer>,
151 mut tmp_slice: Option<usize>,
152 mut escape: bool,
153 mut char_pointer: usize,
154) -> LexResult<GenericObjectIndex> {
155 let char = lexer_vec.pop();
156 if let Some(c) = char {
157 char_pointer += 1;
158 if !escape {
159 match c {
160 LEX_ESCAPE => {
161 generic_object_index(lexer_vec, collect, slicer, tmp_slice, true, char_pointer)
162 }
163 LEX_GENERIC_END => {
164 if collect.is_empty() && slicer.is_empty() {
165 Ok(GenericObjectIndex::Wildcard)
166 } else if !collect.is_empty() {
167 if let Some(from) = tmp_slice {
168 let to = collect.parse::<usize>().map_err(LexerError::from)?;
169 slicer.push_back(Slicer::Slice(from, to));
170 tmp_slice = None;
171 } else if let Ok(u) = collect.parse::<usize>() {
172 slicer.push_back(Slicer::Index(u));
173 } else {
174 slicer.push_back(Slicer::Ident(collect.clone()));
175 }
176 Ok(GenericObjectIndex::Slice(slicer))
177 } else {
178 Ok(GenericObjectIndex::Slice(slicer))
179 }
180 }
181 LEX_GENERIC_SEPARATOR => {
182 if collect.is_empty() && slicer.is_empty() {
183 Err(LexerError::UnexpectedCharacter {
184 expected: "Integer/String".to_string(),
185 found: LEX_GENERIC_SEPARATOR.to_string(),
186 char_pointer,
187 lex: format!("{:?}", lexer_vec),
188 })
189 } else {
190 if let Some(from) = tmp_slice {
191 let to = collect.parse::<usize>().map_err(LexerError::from)?;
192 slicer.push_back(Slicer::Slice(from, to));
193 tmp_slice = None;
194 } else if let Ok(u) = collect.parse::<usize>() {
195 slicer.push_back(Slicer::Index(u));
196 } else {
197 slicer.push_back(Slicer::Ident(collect.clone()));
198 }
199 collect = Default::default();
200 generic_object_index(
201 lexer_vec,
202 collect,
203 slicer,
204 tmp_slice,
205 false,
206 char_pointer,
207 )
208 }
209 }
210 LEX_GENERIC_SLICE => {
211 if collect.is_empty() && slicer.is_empty() {
212 return Err(LexerError::UnexpectedCharacter {
213 expected: "Integer/String".to_string(),
214 found: LEX_GENERIC_SEPARATOR.to_string(),
215 char_pointer,
216 lex: format!("{:?}", lexer_vec),
217 });
218 } else if let Ok(u) = collect.parse::<usize>() {
219 tmp_slice = Some(u);
220 } else {
221 return Err(LexerError::UnexpectedCharacter {
222 expected: "Integer".to_string(),
223 found: "String".to_string(),
224 char_pointer,
225 lex: format!("{:?}", lexer_vec),
226 });
227 }
228 collect = Default::default();
229 generic_object_index(lexer_vec, collect, slicer, tmp_slice, false, char_pointer)
230 }
231 LEX_ROUGE_WIDESPACE => {
232 generic_object_index(lexer_vec, collect, slicer, tmp_slice, false, char_pointer)
233 }
234 _ => {
235 collect.push(c);
236 generic_object_index(lexer_vec, collect, slicer, tmp_slice, false, char_pointer)
237 }
238 }
239 } else {
240 collect.push(c);
241 generic_object_index(lexer_vec, collect, slicer, tmp_slice, false, char_pointer)
242 }
243 } else {
244 Err(LexerError::EndOfQuery {
245 expected: String::from(LEX_GENERIC_END),
246 char_pointer,
247 lex: format!("{:?}", lexer_vec),
248 })
249 }
250}
251
252#[cfg(test)]
253mod test {
254 use crate::lexer::LexOperator::*;
255 use crate::lexer::Slicer::*;
256 use crate::lexer::{
257 compile, generic_compiler, generic_object_index, GenericObjectIndex, LexOperator,
258 LexResult, Slicer,
259 };
260 use crate::LexicalOperations;
261 use std::collections::LinkedList;
262
263 fn lex_vec(s: &str) -> Vec<char> {
264 s.chars().into_iter().collect::<Vec<char>>()
265 }
266
267 #[test]
268 pub fn test_slicer() {
269 let mut lex_vec = lex_vec("1,2,4-6,hello]");
270 lex_vec.reverse();
271 let slicer = generic_object_index(
272 &mut lex_vec,
273 "".to_string(),
274 LinkedList::new(),
275 None,
276 false,
277 0usize,
278 );
279 let true_generic_object = GenericObjectIndex::Slice(LinkedList::from([
280 Slicer::Index(1),
281 Slicer::Index(2),
282 Slicer::Slice(4, 6),
283 Ident("hello".to_string()),
284 ]));
285
286 assert_eq!(true_generic_object, slicer.unwrap())
287 }
288
289 #[test]
290 pub fn test_generic_compiler() {
291 let mut lex_vec = lex_vec(".metadata[1,2,4-6,hello]");
292 lex_vec.reverse();
293 let mut operator = LinkedList::new();
294 let compiled_lex = generic_compiler(
295 &mut lex_vec,
296 &mut operator,
297 Default::default(),
298 false,
299 Default::default(),
300 );
301 let true_result: LexResult<LinkedList<LexOperator>> = Ok(LinkedList::from([
302 Identifier("metadata".to_string()),
303 Generic(GenericObjectIndex::Slice(LinkedList::from([
304 Index(1),
305 Index(2),
306 Slice(4, 6),
307 Ident("hello".to_string()),
308 ]))),
309 ]));
310 assert_eq!(true_result, compiled_lex);
311 }
312
313 #[test]
314 pub fn test_compiler() {
315 let compiled_lex = compile(".metadata[1,2,4-6,hello]");
316 let true_result: LexResult<LexicalOperations> = Ok(LinkedList::from([
317 Identifier("metadata".to_string()),
318 Generic(GenericObjectIndex::Slice(LinkedList::from([
319 Index(1),
320 Index(2),
321 Slice(4, 6),
322 Ident("hello".to_string()),
323 ]))),
324 ])
325 .into());
326 assert_eq!(true_result, compiled_lex);
327 }
328
329 #[test]
330 pub fn test_lex_escape() {
331 let compiled_lex = compile(".metadata[1,2\\,,4-6,hello]");
332 let true_result: LexResult<LexicalOperations> = Ok(LinkedList::from([
333 Identifier("metadata".to_string()),
334 Generic(GenericObjectIndex::Slice(LinkedList::from([
335 Index(1),
336 Ident("2,".to_string()),
337 Slice(4, 6),
338 Ident("hello".to_string()),
339 ]))),
340 ])
341 .into());
342 assert_eq!(true_result, compiled_lex);
343 }
344
345 #[test]
346 pub fn test_lex_escape_identifier() {
347 let compiled_lex = compile(".meta\\.data[1,2\\,,4-6,hello]");
348 let true_result: LexResult<LexicalOperations> = Ok(LinkedList::from([
349 Identifier("meta.data".to_string()),
350 Generic(GenericObjectIndex::Slice(LinkedList::from([
351 Index(1),
352 Ident("2,".to_string()),
353 Slice(4, 6),
354 Ident("hello".to_string()),
355 ]))),
356 ])
357 .into());
358 assert_eq!(true_result, compiled_lex);
359 }
360}
361
362