1 | mod path_reader; |
2 | mod tokenizer; |
3 | |
4 | use std::str::FromStr; |
5 | |
6 | use self::tokenizer::*; |
7 | |
8 | const DUMMY: usize = 0; |
9 | |
10 | type ParseResult<T> = Result<T, String>; |
11 | |
12 | mod utils { |
13 | use std::str::FromStr; |
14 | |
15 | pub fn string_to_num<F, S: FromStr>(string: &str, msg_handler: F) -> Result<S, String> |
16 | where |
17 | F: Fn() -> String, |
18 | { |
19 | match string.parse() { |
20 | Ok(n: S) => Ok(n), |
21 | _ => Err(msg_handler()), |
22 | } |
23 | } |
24 | } |
25 | |
26 | #[derive (Debug, PartialEq, Clone)] |
27 | pub enum ParseToken { |
28 | // '$' |
29 | Absolute, |
30 | // '@' |
31 | Relative, |
32 | // '.' |
33 | In, |
34 | // '..' |
35 | Leaves, |
36 | // '*' |
37 | All, |
38 | |
39 | Key(String), |
40 | Keys(Vec<String>), |
41 | // [] |
42 | Array, |
43 | // 메타토큰 |
44 | ArrayEof, |
45 | // ?( filter ) |
46 | Filter(FilterToken), |
47 | // 1 : 2 |
48 | Range(Option<isize>, Option<isize>, Option<usize>), |
49 | // 1, 2, 3 |
50 | Union(Vec<isize>), |
51 | |
52 | Number(f64), |
53 | |
54 | Bool(bool), |
55 | |
56 | Eof, |
57 | } |
58 | |
59 | #[derive (Debug, PartialEq, Clone)] |
60 | pub enum FilterToken { |
61 | Equal, |
62 | NotEqual, |
63 | Little, |
64 | LittleOrEqual, |
65 | Greater, |
66 | GreaterOrEqual, |
67 | And, |
68 | Or, |
69 | } |
70 | |
71 | #[derive (Debug, Clone)] |
72 | pub struct Node { |
73 | left: Option<Box<Node>>, |
74 | right: Option<Box<Node>>, |
75 | token: ParseToken, |
76 | } |
77 | |
78 | pub struct Parser; |
79 | |
80 | impl Parser { |
81 | pub fn compile(input: &str) -> ParseResult<Node> { |
82 | let mut tokenizer = TokenReader::new(input); |
83 | Self::json_path(&mut tokenizer) |
84 | } |
85 | |
86 | fn json_path(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
87 | debug!("#json_path" ); |
88 | match tokenizer.next_token() { |
89 | Ok(Token::Absolute(_)) => { |
90 | let node = Self::node(ParseToken::Absolute); |
91 | Self::paths(node, tokenizer) |
92 | } |
93 | _ => Err(tokenizer.err_msg()), |
94 | } |
95 | } |
96 | |
97 | fn paths(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
98 | debug!("#paths" ); |
99 | match tokenizer.peek_token() { |
100 | Ok(Token::Dot(_)) => { |
101 | Self::eat_token(tokenizer); |
102 | Self::paths_dot(prev, tokenizer) |
103 | } |
104 | Ok(Token::OpenArray(_)) => { |
105 | Self::eat_token(tokenizer); |
106 | Self::eat_whitespace(tokenizer); |
107 | let node = Self::array(prev, tokenizer)?; |
108 | Self::paths(node, tokenizer) |
109 | } |
110 | _ => Ok(prev), |
111 | } |
112 | } |
113 | |
114 | fn paths_dot(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
115 | debug!("#paths_dot" ); |
116 | let node = Self::path(prev, tokenizer)?; |
117 | Self::paths(node, tokenizer) |
118 | } |
119 | |
120 | fn path(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
121 | debug!("#path" ); |
122 | match tokenizer.peek_token() { |
123 | Ok(Token::Dot(_)) => Self::path_leaves(prev, tokenizer), |
124 | Ok(Token::Asterisk(_)) => Self::path_in_all(prev, tokenizer), |
125 | Ok(Token::Key(_, _)) => Self::path_in_key(prev, tokenizer), |
126 | Ok(Token::OpenArray(_)) => { |
127 | Self::eat_token(tokenizer); |
128 | Self::array(prev, tokenizer) |
129 | } |
130 | _ => Err(tokenizer.err_msg()), |
131 | } |
132 | } |
133 | |
134 | fn path_leaves(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
135 | debug!("#path_leaves" ); |
136 | Self::eat_token(tokenizer); |
137 | match tokenizer.peek_token() { |
138 | Ok(Token::Asterisk(_)) => Self::path_leaves_all(prev, tokenizer), |
139 | Ok(Token::OpenArray(_)) => { |
140 | let mut leaves_node = Self::node(ParseToken::Leaves); |
141 | leaves_node.left = Some(Box::new(prev)); |
142 | Ok(Self::paths(leaves_node, tokenizer)?) |
143 | } |
144 | _ => Self::path_leaves_key(prev, tokenizer), |
145 | } |
146 | } |
147 | |
148 | #[allow (clippy::unnecessary_wraps)] |
149 | fn path_leaves_key(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
150 | debug!("#path_leaves_key" ); |
151 | Ok(Node { |
152 | token: ParseToken::Leaves, |
153 | left: Some(Box::new(prev)), |
154 | right: Some(Box::new(Self::key(tokenizer)?)), |
155 | }) |
156 | } |
157 | |
158 | #[allow (clippy::unnecessary_wraps)] |
159 | fn path_leaves_all(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
160 | debug!("#path_leaves_all" ); |
161 | Self::eat_token(tokenizer); |
162 | Ok(Node { |
163 | token: ParseToken::Leaves, |
164 | left: Some(Box::new(prev)), |
165 | right: Some(Box::new(Self::node(ParseToken::All))), |
166 | }) |
167 | } |
168 | |
169 | #[allow (clippy::unnecessary_wraps)] |
170 | fn path_in_all(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
171 | debug!("#path_in_all" ); |
172 | Self::eat_token(tokenizer); |
173 | Ok(Node { |
174 | token: ParseToken::In, |
175 | left: Some(Box::new(prev)), |
176 | right: Some(Box::new(Self::node(ParseToken::All))), |
177 | }) |
178 | } |
179 | |
180 | #[allow (clippy::unnecessary_wraps)] |
181 | fn path_in_key(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
182 | debug!("#path_in_key" ); |
183 | Ok(Node { |
184 | token: ParseToken::In, |
185 | left: Some(Box::new(prev)), |
186 | right: Some(Box::new(Self::key(tokenizer)?)), |
187 | }) |
188 | } |
189 | |
190 | fn key(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
191 | debug!("#key" ); |
192 | match tokenizer.next_token() { |
193 | Ok(Token::Key(_, v)) => Ok(Self::node(ParseToken::Key(v))), |
194 | _ => Err(tokenizer.err_msg()), |
195 | } |
196 | } |
197 | |
198 | fn boolean(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
199 | debug!("#boolean" ); |
200 | |
201 | fn validation_bool_value(v: &str) -> bool { |
202 | let b = v.as_bytes(); |
203 | !b.is_empty() && (b[0] == b't' || b[0] == b'T' || b[0] == b'f' || b[0] == b'F' ) |
204 | } |
205 | |
206 | match tokenizer.next_token() { |
207 | Ok(Token::Key(_, ref v)) if validation_bool_value(v) => { |
208 | Ok(Self::node(ParseToken::Bool(v.eq_ignore_ascii_case("true" )))) |
209 | } |
210 | _ => Err(tokenizer.err_msg()), |
211 | } |
212 | } |
213 | |
214 | fn array_keys(tokenizer: &mut TokenReader, first_key: String) -> ParseResult<Node> { |
215 | let mut keys = vec![first_key]; |
216 | |
217 | while let Ok(Token::Comma(_)) = tokenizer.peek_token() { |
218 | Self::eat_token(tokenizer); |
219 | Self::eat_whitespace(tokenizer); |
220 | |
221 | match tokenizer.next_token() { |
222 | Ok(Token::SingleQuoted(_, val)) | Ok(Token::DoubleQuoted(_, val)) => { |
223 | keys.push(val); |
224 | } |
225 | _ => return Err(tokenizer.err_msg()), |
226 | } |
227 | |
228 | Self::eat_whitespace(tokenizer); |
229 | } |
230 | |
231 | Ok(Self::node(ParseToken::Keys(keys))) |
232 | } |
233 | |
234 | fn array_quote_value(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
235 | debug!("#array_quote_value" ); |
236 | match tokenizer.next_token() { |
237 | Ok(Token::SingleQuoted(_, val)) | Ok(Token::DoubleQuoted(_, val)) => { |
238 | if let Ok(Token::Comma(_)) = tokenizer.peek_token() { |
239 | Self::array_keys(tokenizer, val) |
240 | } else { |
241 | Ok(Self::node(ParseToken::Key(val))) |
242 | } |
243 | } |
244 | _ => Err(tokenizer.err_msg()), |
245 | } |
246 | } |
247 | |
248 | fn array_start(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
249 | debug!("#array_start" ); |
250 | match tokenizer.peek_token() { |
251 | Ok(Token::Question(_)) => { |
252 | Self::eat_token(tokenizer); |
253 | Ok(Node { |
254 | token: ParseToken::Array, |
255 | left: Some(Box::new(prev)), |
256 | right: Some(Box::new(Self::filter(tokenizer)?)), |
257 | }) |
258 | } |
259 | Ok(Token::Asterisk(_)) => { |
260 | Self::eat_token(tokenizer); |
261 | Ok(Node { |
262 | token: ParseToken::Array, |
263 | left: Some(Box::new(prev)), |
264 | right: Some(Box::new(Self::node(ParseToken::All))), |
265 | }) |
266 | } |
267 | _ => Ok(Node { |
268 | token: ParseToken::Array, |
269 | left: Some(Box::new(prev)), |
270 | right: Some(Box::new(Self::array_value(tokenizer)?)), |
271 | }), |
272 | } |
273 | } |
274 | |
275 | fn array(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
276 | debug!("#array" ); |
277 | let ret = Self::array_start(prev, tokenizer)?; |
278 | Self::eat_whitespace(tokenizer); |
279 | Self::close_token(ret, Token::CloseArray(DUMMY), tokenizer) |
280 | } |
281 | |
282 | fn array_value_key(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
283 | debug!("#array_value_key" ); |
284 | match tokenizer.next_token() { |
285 | Ok(Token::Key(pos, ref val)) => { |
286 | let digit = utils::string_to_num(val, || tokenizer.err_msg_with_pos(pos))?; |
287 | Self::eat_whitespace(tokenizer); |
288 | |
289 | match tokenizer.peek_token() { |
290 | Ok(Token::Comma(_)) => Self::union(digit, tokenizer), |
291 | Ok(Token::Split(_)) => Self::range_from(digit, tokenizer), |
292 | _ => Ok(Self::node(ParseToken::Number(digit as f64))), |
293 | } |
294 | } |
295 | _ => Err(tokenizer.err_msg()), |
296 | } |
297 | } |
298 | |
299 | fn array_value(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
300 | debug!("#array_value" ); |
301 | match tokenizer.peek_token() { |
302 | Ok(Token::Key(_, _)) => Self::array_value_key(tokenizer), |
303 | Ok(Token::Split(_)) => { |
304 | Self::eat_token(tokenizer); |
305 | Self::range_to(tokenizer) |
306 | } |
307 | Ok(Token::DoubleQuoted(_, _)) | Ok(Token::SingleQuoted(_, _)) => { |
308 | Self::array_quote_value(tokenizer) |
309 | } |
310 | Err(TokenError::Eof) => Ok(Self::node(ParseToken::Eof)), |
311 | _ => { |
312 | Self::eat_token(tokenizer); |
313 | Err(tokenizer.err_msg()) |
314 | } |
315 | } |
316 | } |
317 | |
318 | fn union(num: isize, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
319 | debug!("#union" ); |
320 | let mut values = vec![num]; |
321 | while matches!(tokenizer.peek_token(), Ok(Token::Comma(_))) { |
322 | Self::eat_token(tokenizer); |
323 | Self::eat_whitespace(tokenizer); |
324 | match tokenizer.next_token() { |
325 | Ok(Token::Key(pos, ref val)) => { |
326 | let digit = utils::string_to_num(val, || tokenizer.err_msg_with_pos(pos))?; |
327 | values.push(digit); |
328 | } |
329 | _ => { |
330 | return Err(tokenizer.err_msg()); |
331 | } |
332 | } |
333 | } |
334 | Ok(Self::node(ParseToken::Union(values))) |
335 | } |
336 | |
337 | fn range_value<S: FromStr>(tokenizer: &mut TokenReader) -> Result<Option<S>, String> { |
338 | Self::eat_whitespace(tokenizer); |
339 | |
340 | match tokenizer.peek_token() { |
341 | Ok(Token::Split(_)) => { |
342 | Self::eat_token(tokenizer); |
343 | Self::eat_whitespace(tokenizer); |
344 | } |
345 | _ => { |
346 | return Ok(None); |
347 | } |
348 | } |
349 | |
350 | match tokenizer.peek_token() { |
351 | Ok(Token::Key(_, _)) => {} |
352 | _ => { |
353 | return Ok(None); |
354 | } |
355 | } |
356 | |
357 | match tokenizer.next_token() { |
358 | Ok(Token::Key(pos, str_step)) => { |
359 | match utils::string_to_num(&str_step, || tokenizer.err_msg_with_pos(pos)) { |
360 | Ok(step) => Ok(Some(step)), |
361 | Err(e) => Err(e), |
362 | } |
363 | } |
364 | _ => { |
365 | unreachable!(); |
366 | } |
367 | } |
368 | } |
369 | |
370 | fn range_from(from: isize, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
371 | debug!("#range_from" ); |
372 | Self::eat_token(tokenizer); |
373 | Self::eat_whitespace(tokenizer); |
374 | |
375 | match tokenizer.peek_token() { |
376 | Ok(Token::Key(_, _)) => Self::range(from, tokenizer), |
377 | Ok(Token::Split(_)) => match Self::range_value(tokenizer)? { |
378 | Some(step) => Ok(Self::node(ParseToken::Range(Some(from), None, Some(step)))), |
379 | _ => Ok(Self::node(ParseToken::Range(Some(from), None, None))), |
380 | }, |
381 | _ => Ok(Self::node(ParseToken::Range(Some(from), None, None))), |
382 | } |
383 | } |
384 | |
385 | fn range_to(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
386 | debug!("#range_to" ); |
387 | |
388 | if let Some(step) = Self::range_value(tokenizer)? { |
389 | return Ok(Self::node(ParseToken::Range(None, None, Some(step)))); |
390 | } |
391 | |
392 | if let Ok(Token::CloseArray(_)) = tokenizer.peek_token() { |
393 | return Ok(Self::node(ParseToken::Range(None, None, None))); |
394 | } |
395 | |
396 | match tokenizer.next_token() { |
397 | Ok(Token::Key(pos, ref to_str)) => { |
398 | let to = utils::string_to_num(to_str, || tokenizer.err_msg_with_pos(pos))?; |
399 | let step = Self::range_value(tokenizer)?; |
400 | Ok(Self::node(ParseToken::Range(None, Some(to), step))) |
401 | } |
402 | _ => Err(tokenizer.err_msg()), |
403 | } |
404 | } |
405 | |
406 | fn range(from: isize, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
407 | debug!("#range" ); |
408 | match tokenizer.next_token() { |
409 | Ok(Token::Key(pos, ref str_to)) => { |
410 | let to = utils::string_to_num(str_to, || tokenizer.err_msg_with_pos(pos))?; |
411 | let step = Self::range_value(tokenizer)?; |
412 | Ok(Self::node(ParseToken::Range(Some(from), Some(to), step))) |
413 | } |
414 | _ => Err(tokenizer.err_msg()), |
415 | } |
416 | } |
417 | |
418 | fn filter(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
419 | debug!("#filter" ); |
420 | match tokenizer.next_token() { |
421 | Ok(Token::OpenParenthesis(_)) => { |
422 | let ret = Self::exprs(tokenizer)?; |
423 | Self::eat_whitespace(tokenizer); |
424 | Self::close_token(ret, Token::CloseParenthesis(DUMMY), tokenizer) |
425 | } |
426 | _ => Err(tokenizer.err_msg()), |
427 | } |
428 | } |
429 | |
430 | fn exprs(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
431 | Self::eat_whitespace(tokenizer); |
432 | debug!("#exprs" ); |
433 | let node = match tokenizer.peek_token() { |
434 | Ok(Token::OpenParenthesis(_)) => { |
435 | Self::eat_token(tokenizer); |
436 | trace!(" \t-exprs - open_parenthesis" ); |
437 | let ret = Self::exprs(tokenizer)?; |
438 | Self::eat_whitespace(tokenizer); |
439 | Self::close_token(ret, Token::CloseParenthesis(DUMMY), tokenizer)? |
440 | } |
441 | _ => { |
442 | trace!(" \t-exprs - else" ); |
443 | Self::expr(tokenizer)? |
444 | } |
445 | }; |
446 | Self::eat_whitespace(tokenizer); |
447 | Self::condition_expr(node, tokenizer) |
448 | } |
449 | |
450 | fn condition_expr(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
451 | debug!("#condition_expr" ); |
452 | match tokenizer.peek_token() { |
453 | Ok(Token::And(_)) => { |
454 | Self::eat_token(tokenizer); |
455 | Ok(Node { |
456 | token: ParseToken::Filter(FilterToken::And), |
457 | left: Some(Box::new(prev)), |
458 | right: Some(Box::new(Self::exprs(tokenizer)?)), |
459 | }) |
460 | } |
461 | Ok(Token::Or(_)) => { |
462 | Self::eat_token(tokenizer); |
463 | Ok(Node { |
464 | token: ParseToken::Filter(FilterToken::Or), |
465 | left: Some(Box::new(prev)), |
466 | right: Some(Box::new(Self::exprs(tokenizer)?)), |
467 | }) |
468 | } |
469 | _ => Ok(prev), |
470 | } |
471 | } |
472 | |
473 | fn expr(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
474 | debug!("#expr" ); |
475 | |
476 | let has_prop_candidate = matches!(tokenizer.peek_token(), Ok(Token::At(_))); |
477 | |
478 | let node = Self::term(tokenizer)?; |
479 | Self::eat_whitespace(tokenizer); |
480 | |
481 | if matches!(tokenizer.peek_token(), |
482 | Ok(Token::Equal(_)) |
483 | | Ok(Token::NotEqual(_)) |
484 | | Ok(Token::Little(_)) |
485 | | Ok(Token::LittleOrEqual(_)) |
486 | | Ok(Token::Greater(_)) |
487 | | Ok(Token::GreaterOrEqual(_))) |
488 | { |
489 | Self::op(node, tokenizer) |
490 | } else if has_prop_candidate { |
491 | Ok(node) |
492 | } else { |
493 | Err(tokenizer.err_msg()) |
494 | } |
495 | } |
496 | |
497 | fn term_num(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
498 | debug!("#term_num" ); |
499 | match tokenizer.next_token() { |
500 | Ok(Token::Key(pos, val)) => match tokenizer.peek_token() { |
501 | Ok(Token::Dot(_)) => Self::term_num_float(val.as_str(), tokenizer), |
502 | _ => { |
503 | let number = utils::string_to_num(&val, || tokenizer.err_msg_with_pos(pos))?; |
504 | Ok(Self::node(ParseToken::Number(number))) |
505 | } |
506 | }, |
507 | _ => Err(tokenizer.err_msg()), |
508 | } |
509 | } |
510 | |
511 | fn term_num_float(num: &str, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
512 | debug!("#term_num_float" ); |
513 | Self::eat_token(tokenizer); |
514 | match tokenizer.next_token() { |
515 | Ok(Token::Key(pos, frac)) => { |
516 | let mut f = String::new(); |
517 | f.push_str(&num); |
518 | f.push('.' ); |
519 | f.push_str(frac.as_str()); |
520 | let number = utils::string_to_num(&f, || tokenizer.err_msg_with_pos(pos))?; |
521 | Ok(Self::node(ParseToken::Number(number))) |
522 | } |
523 | _ => Err(tokenizer.err_msg()), |
524 | } |
525 | } |
526 | |
527 | fn term(tokenizer: &mut TokenReader) -> ParseResult<Node> { |
528 | debug!("#term" ); |
529 | |
530 | match tokenizer.peek_token() { |
531 | Ok(Token::At(_)) => { |
532 | Self::eat_token(tokenizer); |
533 | let node = Self::node(ParseToken::Relative); |
534 | |
535 | match tokenizer.peek_token() { |
536 | Ok(Token::Whitespace(_, _)) => { |
537 | Self::eat_whitespace(tokenizer); |
538 | Ok(node) |
539 | } |
540 | _ => Self::paths(node, tokenizer), |
541 | } |
542 | } |
543 | Ok(Token::Absolute(_)) => { |
544 | Self::json_path(tokenizer) |
545 | } |
546 | Ok(Token::DoubleQuoted(_, _)) | Ok(Token::SingleQuoted(_, _)) => { |
547 | Self::array_quote_value(tokenizer) |
548 | } |
549 | Ok(Token::Key(_, key)) => { |
550 | match key.as_bytes()[0] { |
551 | b'-' | b'0' ..=b'9' => Self::term_num(tokenizer), |
552 | _ => Self::boolean(tokenizer), |
553 | } |
554 | } |
555 | _ => { |
556 | Err(tokenizer.err_msg()) |
557 | } |
558 | } |
559 | } |
560 | |
561 | fn op(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
562 | debug!("#op" ); |
563 | let token = match tokenizer.next_token() { |
564 | Ok(Token::Equal(_)) => ParseToken::Filter(FilterToken::Equal), |
565 | Ok(Token::NotEqual(_)) => ParseToken::Filter(FilterToken::NotEqual), |
566 | Ok(Token::Little(_)) => ParseToken::Filter(FilterToken::Little), |
567 | Ok(Token::LittleOrEqual(_)) => ParseToken::Filter(FilterToken::LittleOrEqual), |
568 | Ok(Token::Greater(_)) => ParseToken::Filter(FilterToken::Greater), |
569 | Ok(Token::GreaterOrEqual(_)) => ParseToken::Filter(FilterToken::GreaterOrEqual), |
570 | _ => { |
571 | return Err(tokenizer.err_msg()); |
572 | } |
573 | }; |
574 | |
575 | Self::eat_whitespace(tokenizer); |
576 | |
577 | Ok(Node { |
578 | token, |
579 | left: Some(Box::new(prev)), |
580 | right: Some(Box::new(Self::term(tokenizer)?)), |
581 | }) |
582 | } |
583 | |
584 | fn eat_whitespace(tokenizer: &mut TokenReader) { |
585 | while let Ok(Token::Whitespace(_, _)) = tokenizer.peek_token() { |
586 | let _ = tokenizer.next_token(); |
587 | } |
588 | } |
589 | |
590 | fn eat_token(tokenizer: &mut TokenReader) { |
591 | let _ = tokenizer.next_token(); |
592 | } |
593 | |
594 | fn node(token: ParseToken) -> Node { |
595 | Node { |
596 | left: None, |
597 | right: None, |
598 | token, |
599 | } |
600 | } |
601 | |
602 | fn close_token(ret: Node, token: Token, tokenizer: &mut TokenReader) -> ParseResult<Node> { |
603 | debug!("#close_token" ); |
604 | match tokenizer.next_token() { |
605 | Ok(ref t) if t.is_match_token_type(token) => Ok(ret), |
606 | _ => Err(tokenizer.err_msg()), |
607 | } |
608 | } |
609 | } |
610 | |
611 | pub trait NodeVisitor { |
612 | fn visit(&mut self, node: &Node) { |
613 | match &node.token { |
614 | ParseToken::Absolute |
615 | | ParseToken::Relative |
616 | | ParseToken::All |
617 | | ParseToken::Key(_) |
618 | | ParseToken::Keys(_) |
619 | | ParseToken::Range(_, _, _) |
620 | | ParseToken::Union(_) |
621 | | ParseToken::Number(_) |
622 | | ParseToken::Bool(_) => { |
623 | self.visit_token(&node.token); |
624 | } |
625 | ParseToken::In | ParseToken::Leaves => { |
626 | if let Some(n) = &node.left { |
627 | self.visit(&*n); |
628 | } |
629 | |
630 | self.visit_token(&node.token); |
631 | |
632 | if let Some(n) = &node.right { |
633 | self.visit(&*n); |
634 | } |
635 | } |
636 | ParseToken::Array => { |
637 | if let Some(n) = &node.left { |
638 | self.visit(&*n); |
639 | } |
640 | |
641 | self.visit_token(&node.token); |
642 | |
643 | if let Some(n) = &node.right { |
644 | self.visit(&*n); |
645 | } |
646 | |
647 | self.visit_token(&ParseToken::ArrayEof); |
648 | } |
649 | ParseToken::Filter(FilterToken::And) | ParseToken::Filter(FilterToken::Or) => { |
650 | if let Some(n) = &node.left { |
651 | self.visit(&*n); |
652 | } |
653 | |
654 | if let Some(n) = &node.right { |
655 | self.visit(&*n); |
656 | } |
657 | |
658 | self.visit_token(&node.token); |
659 | } |
660 | ParseToken::Filter(_) => { |
661 | if let Some(n) = &node.left { |
662 | self.visit(&*n); |
663 | } |
664 | |
665 | self.end_term(); |
666 | |
667 | if let Some(n) = &node.right { |
668 | self.visit(&*n); |
669 | } |
670 | |
671 | self.end_term(); |
672 | |
673 | self.visit_token(&node.token); |
674 | } |
675 | _ => {} |
676 | } |
677 | } |
678 | |
679 | fn visit_token(&mut self, token: &ParseToken); |
680 | fn end_term(&mut self) {} |
681 | } |
682 | |
683 | #[cfg (test)] |
684 | mod parser_tests { |
685 | use parser::{FilterToken, NodeVisitor, ParseToken, Parser}; |
686 | |
687 | struct NodeVisitorTestImpl<'a> { |
688 | input: &'a str, |
689 | stack: Vec<ParseToken>, |
690 | } |
691 | |
692 | impl<'a> NodeVisitorTestImpl<'a> { |
693 | fn new(input: &'a str) -> Self { |
694 | NodeVisitorTestImpl { |
695 | input, |
696 | stack: Vec::new(), |
697 | } |
698 | } |
699 | |
700 | fn start(&mut self) -> Result<Vec<ParseToken>, String> { |
701 | let node = Parser::compile(self.input)?; |
702 | self.visit(&node); |
703 | Ok(self.stack.split_off(0)) |
704 | } |
705 | } |
706 | |
707 | impl<'a> NodeVisitor for NodeVisitorTestImpl<'a> { |
708 | fn visit_token(&mut self, token: &ParseToken) { |
709 | self.stack.push(token.clone()); |
710 | } |
711 | } |
712 | |
713 | fn setup() { |
714 | let _ = env_logger::try_init(); |
715 | } |
716 | |
717 | fn run(input: &str) -> Result<Vec<ParseToken>, String> { |
718 | let mut interpreter = NodeVisitorTestImpl::new(input); |
719 | interpreter.start() |
720 | } |
721 | |
722 | #[test ] |
723 | fn parse_error() { |
724 | setup(); |
725 | |
726 | fn invalid(path: &str) { |
727 | assert!(run(path).is_err()); |
728 | } |
729 | |
730 | invalid("$[]" ); |
731 | invalid("$[a]" ); |
732 | invalid("$[?($.a)]" ); |
733 | invalid("$[?(@.a > @.b]" ); |
734 | invalid("$[?(@.a < @.b&&(@.c < @.d)]" ); |
735 | invalid("@." ); |
736 | invalid("$..[?(a <= @.a)]" ); // invalid term value |
737 | invalid("$['a', b]" ); |
738 | invalid("$[0, >=]" ); |
739 | invalid("$[a:]" ); |
740 | invalid("$[:a]" ); |
741 | invalid("$[::a]" ); |
742 | invalid("$[:>]" ); |
743 | invalid("$[1:>]" ); |
744 | invalid("$[1,,]" ); |
745 | invalid("$[?]" ); |
746 | invalid("$[?(1 = 1)]" ); |
747 | invalid("$[?(1 = >)]" ); |
748 | } |
749 | |
750 | #[test ] |
751 | fn parse_path() { |
752 | setup(); |
753 | |
754 | assert_eq!( |
755 | run("$.aa" ), |
756 | Ok(vec![ |
757 | ParseToken::Absolute, |
758 | ParseToken::In, |
759 | ParseToken::Key("aa" .to_owned()) |
760 | ]) |
761 | ); |
762 | |
763 | assert_eq!( |
764 | run("$.00.a" ), |
765 | Ok(vec![ |
766 | ParseToken::Absolute, |
767 | ParseToken::In, |
768 | ParseToken::Key("00" .to_owned()), |
769 | ParseToken::In, |
770 | ParseToken::Key("a" .to_owned()) |
771 | ]) |
772 | ); |
773 | |
774 | assert_eq!( |
775 | run("$.00.韓창.seok" ), |
776 | Ok(vec![ |
777 | ParseToken::Absolute, |
778 | ParseToken::In, |
779 | ParseToken::Key("00" .to_owned()), |
780 | ParseToken::In, |
781 | ParseToken::Key("韓창" .to_owned()), |
782 | ParseToken::In, |
783 | ParseToken::Key("seok" .to_owned()) |
784 | ]) |
785 | ); |
786 | |
787 | assert_eq!( |
788 | run("$.*" ), |
789 | Ok(vec![ParseToken::Absolute, ParseToken::In, ParseToken::All]) |
790 | ); |
791 | |
792 | assert_eq!( |
793 | run("$..*" ), |
794 | Ok(vec![ |
795 | ParseToken::Absolute, |
796 | ParseToken::Leaves, |
797 | ParseToken::All |
798 | ]) |
799 | ); |
800 | |
801 | assert_eq!( |
802 | run("$..[0]" ), |
803 | Ok(vec![ |
804 | ParseToken::Absolute, |
805 | ParseToken::Leaves, |
806 | ParseToken::Array, |
807 | ParseToken::Number(0.0), |
808 | ParseToken::ArrayEof |
809 | ]) |
810 | ); |
811 | |
812 | assert_eq!( |
813 | run("$.$a" ), |
814 | Ok(vec![ |
815 | ParseToken::Absolute, |
816 | ParseToken::In, |
817 | ParseToken::Key("$a" .to_owned()) |
818 | ]) |
819 | ); |
820 | |
821 | assert_eq!( |
822 | run("$.['$a']" ), |
823 | Ok(vec![ |
824 | ParseToken::Absolute, |
825 | ParseToken::Array, |
826 | ParseToken::Key("$a" .to_owned()), |
827 | ParseToken::ArrayEof, |
828 | ]) |
829 | ); |
830 | |
831 | if run("$." ).is_ok() { |
832 | panic!(); |
833 | } |
834 | |
835 | if run("$.." ).is_ok() { |
836 | panic!(); |
837 | } |
838 | |
839 | if run("$. a" ).is_ok() { |
840 | panic!(); |
841 | } |
842 | } |
843 | |
844 | #[test ] |
845 | fn parse_array_syntax() { |
846 | setup(); |
847 | |
848 | assert_eq!( |
849 | run("$.book[?(@.isbn)]" ), |
850 | Ok(vec![ |
851 | ParseToken::Absolute, |
852 | ParseToken::In, |
853 | ParseToken::Key("book" .to_string()), |
854 | ParseToken::Array, |
855 | ParseToken::Relative, |
856 | ParseToken::In, |
857 | ParseToken::Key("isbn" .to_string()), |
858 | ParseToken::ArrayEof |
859 | ]) |
860 | ); |
861 | |
862 | // |
863 | // Array도 컨텍스트 In으로 간주 할거라서 중첩되면 하나만 |
864 | // |
865 | assert_eq!( |
866 | run("$.[*]" ), |
867 | Ok(vec![ |
868 | ParseToken::Absolute, |
869 | ParseToken::Array, |
870 | ParseToken::All, |
871 | ParseToken::ArrayEof |
872 | ]) |
873 | ); |
874 | |
875 | assert_eq!( |
876 | run("$.a[*]" ), |
877 | Ok(vec![ |
878 | ParseToken::Absolute, |
879 | ParseToken::In, |
880 | ParseToken::Key("a" .to_owned()), |
881 | ParseToken::Array, |
882 | ParseToken::All, |
883 | ParseToken::ArrayEof |
884 | ]) |
885 | ); |
886 | |
887 | assert_eq!( |
888 | run("$.a[*].가" ), |
889 | Ok(vec![ |
890 | ParseToken::Absolute, |
891 | ParseToken::In, |
892 | ParseToken::Key("a" .to_owned()), |
893 | ParseToken::Array, |
894 | ParseToken::All, |
895 | ParseToken::ArrayEof, |
896 | ParseToken::In, |
897 | ParseToken::Key("가" .to_owned()) |
898 | ]) |
899 | ); |
900 | |
901 | assert_eq!( |
902 | run("$.a[0][1]" ), |
903 | Ok(vec![ |
904 | ParseToken::Absolute, |
905 | ParseToken::In, |
906 | ParseToken::Key("a" .to_owned()), |
907 | ParseToken::Array, |
908 | ParseToken::Number(0_f64), |
909 | ParseToken::ArrayEof, |
910 | ParseToken::Array, |
911 | ParseToken::Number(1_f64), |
912 | ParseToken::ArrayEof |
913 | ]) |
914 | ); |
915 | |
916 | assert_eq!( |
917 | run("$.a[1,2]" ), |
918 | Ok(vec![ |
919 | ParseToken::Absolute, |
920 | ParseToken::In, |
921 | ParseToken::Key("a" .to_owned()), |
922 | ParseToken::Array, |
923 | ParseToken::Union(vec![1, 2]), |
924 | ParseToken::ArrayEof |
925 | ]) |
926 | ); |
927 | |
928 | assert_eq!( |
929 | run("$.a[10:]" ), |
930 | Ok(vec![ |
931 | ParseToken::Absolute, |
932 | ParseToken::In, |
933 | ParseToken::Key("a" .to_owned()), |
934 | ParseToken::Array, |
935 | ParseToken::Range(Some(10), None, None), |
936 | ParseToken::ArrayEof |
937 | ]) |
938 | ); |
939 | |
940 | assert_eq!( |
941 | run("$.a[:11]" ), |
942 | Ok(vec![ |
943 | ParseToken::Absolute, |
944 | ParseToken::In, |
945 | ParseToken::Key("a" .to_owned()), |
946 | ParseToken::Array, |
947 | ParseToken::Range(None, Some(11), None), |
948 | ParseToken::ArrayEof |
949 | ]) |
950 | ); |
951 | |
952 | assert_eq!( |
953 | run("$.a[-12:13]" ), |
954 | Ok(vec![ |
955 | ParseToken::Absolute, |
956 | ParseToken::In, |
957 | ParseToken::Key("a" .to_owned()), |
958 | ParseToken::Array, |
959 | ParseToken::Range(Some(-12), Some(13), None), |
960 | ParseToken::ArrayEof |
961 | ]) |
962 | ); |
963 | |
964 | assert_eq!( |
965 | run(r#"$[0:3:2]"# ), |
966 | Ok(vec![ |
967 | ParseToken::Absolute, |
968 | ParseToken::Array, |
969 | ParseToken::Range(Some(0), Some(3), Some(2)), |
970 | ParseToken::ArrayEof |
971 | ]) |
972 | ); |
973 | |
974 | assert_eq!( |
975 | run(r#"$[:3:2]"# ), |
976 | Ok(vec![ |
977 | ParseToken::Absolute, |
978 | ParseToken::Array, |
979 | ParseToken::Range(None, Some(3), Some(2)), |
980 | ParseToken::ArrayEof |
981 | ]) |
982 | ); |
983 | |
984 | assert_eq!( |
985 | run(r#"$[:]"# ), |
986 | Ok(vec![ |
987 | ParseToken::Absolute, |
988 | ParseToken::Array, |
989 | ParseToken::Range(None, None, None), |
990 | ParseToken::ArrayEof |
991 | ]) |
992 | ); |
993 | |
994 | assert_eq!( |
995 | run(r#"$[::]"# ), |
996 | Ok(vec![ |
997 | ParseToken::Absolute, |
998 | ParseToken::Array, |
999 | ParseToken::Range(None, None, None), |
1000 | ParseToken::ArrayEof |
1001 | ]) |
1002 | ); |
1003 | |
1004 | assert_eq!( |
1005 | run(r#"$[::2]"# ), |
1006 | Ok(vec![ |
1007 | ParseToken::Absolute, |
1008 | ParseToken::Array, |
1009 | ParseToken::Range(None, None, Some(2)), |
1010 | ParseToken::ArrayEof |
1011 | ]) |
1012 | ); |
1013 | |
1014 | assert_eq!( |
1015 | run(r#"$["a", 'b']"# ), |
1016 | Ok(vec![ |
1017 | ParseToken::Absolute, |
1018 | ParseToken::Array, |
1019 | ParseToken::Keys(vec!["a" .to_string(), "b" .to_string()]), |
1020 | ParseToken::ArrayEof |
1021 | ]) |
1022 | ); |
1023 | |
1024 | assert_eq!( |
1025 | run("$.a[?(1>2)]" ), |
1026 | Ok(vec![ |
1027 | ParseToken::Absolute, |
1028 | ParseToken::In, |
1029 | ParseToken::Key("a" .to_owned()), |
1030 | ParseToken::Array, |
1031 | ParseToken::Number(1_f64), |
1032 | ParseToken::Number(2_f64), |
1033 | ParseToken::Filter(FilterToken::Greater), |
1034 | ParseToken::ArrayEof |
1035 | ]) |
1036 | ); |
1037 | |
1038 | assert_eq!( |
1039 | run("$.a[?($.b>3)]" ), |
1040 | Ok(vec![ |
1041 | ParseToken::Absolute, |
1042 | ParseToken::In, |
1043 | ParseToken::Key("a" .to_owned()), |
1044 | ParseToken::Array, |
1045 | ParseToken::Absolute, |
1046 | ParseToken::In, |
1047 | ParseToken::Key("b" .to_owned()), |
1048 | ParseToken::Number(3_f64), |
1049 | ParseToken::Filter(FilterToken::Greater), |
1050 | ParseToken::ArrayEof |
1051 | ]) |
1052 | ); |
1053 | |
1054 | assert_eq!( |
1055 | run("$[?($.c>@.d && 1==2)]" ), |
1056 | Ok(vec![ |
1057 | ParseToken::Absolute, |
1058 | ParseToken::Array, |
1059 | ParseToken::Absolute, |
1060 | ParseToken::In, |
1061 | ParseToken::Key("c" .to_owned()), |
1062 | ParseToken::Relative, |
1063 | ParseToken::In, |
1064 | ParseToken::Key("d" .to_owned()), |
1065 | ParseToken::Filter(FilterToken::Greater), |
1066 | ParseToken::Number(1_f64), |
1067 | ParseToken::Number(2_f64), |
1068 | ParseToken::Filter(FilterToken::Equal), |
1069 | ParseToken::Filter(FilterToken::And), |
1070 | ParseToken::ArrayEof |
1071 | ]) |
1072 | ); |
1073 | |
1074 | assert_eq!( |
1075 | run("$[?($.c>@.d&&(1==2||3>=4))]" ), |
1076 | Ok(vec![ |
1077 | ParseToken::Absolute, |
1078 | ParseToken::Array, |
1079 | ParseToken::Absolute, |
1080 | ParseToken::In, |
1081 | ParseToken::Key("c" .to_owned()), |
1082 | ParseToken::Relative, |
1083 | ParseToken::In, |
1084 | ParseToken::Key("d" .to_owned()), |
1085 | ParseToken::Filter(FilterToken::Greater), |
1086 | ParseToken::Number(1_f64), |
1087 | ParseToken::Number(2_f64), |
1088 | ParseToken::Filter(FilterToken::Equal), |
1089 | ParseToken::Number(3_f64), |
1090 | ParseToken::Number(4_f64), |
1091 | ParseToken::Filter(FilterToken::GreaterOrEqual), |
1092 | ParseToken::Filter(FilterToken::Or), |
1093 | ParseToken::Filter(FilterToken::And), |
1094 | ParseToken::ArrayEof |
1095 | ]) |
1096 | ); |
1097 | |
1098 | assert_eq!( |
1099 | run("$[?(@.a<@.b)]" ), |
1100 | Ok(vec![ |
1101 | ParseToken::Absolute, |
1102 | ParseToken::Array, |
1103 | ParseToken::Relative, |
1104 | ParseToken::In, |
1105 | ParseToken::Key("a" .to_owned()), |
1106 | ParseToken::Relative, |
1107 | ParseToken::In, |
1108 | ParseToken::Key("b" .to_owned()), |
1109 | ParseToken::Filter(FilterToken::Little), |
1110 | ParseToken::ArrayEof |
1111 | ]) |
1112 | ); |
1113 | |
1114 | assert_eq!( |
1115 | run("$[*][*][*]" ), |
1116 | Ok(vec![ |
1117 | ParseToken::Absolute, |
1118 | ParseToken::Array, |
1119 | ParseToken::All, |
1120 | ParseToken::ArrayEof, |
1121 | ParseToken::Array, |
1122 | ParseToken::All, |
1123 | ParseToken::ArrayEof, |
1124 | ParseToken::Array, |
1125 | ParseToken::All, |
1126 | ParseToken::ArrayEof |
1127 | ]) |
1128 | ); |
1129 | |
1130 | assert_eq!( |
1131 | run("$['a']['bb']" ), |
1132 | Ok(vec![ |
1133 | ParseToken::Absolute, |
1134 | ParseToken::Array, |
1135 | ParseToken::Key("a" .to_string()), |
1136 | ParseToken::ArrayEof, |
1137 | ParseToken::Array, |
1138 | ParseToken::Key("bb" .to_string()), |
1139 | ParseToken::ArrayEof |
1140 | ]) |
1141 | ); |
1142 | |
1143 | assert_eq!( |
1144 | run("$.a[?(@.e==true)]" ), |
1145 | Ok(vec![ |
1146 | ParseToken::Absolute, |
1147 | ParseToken::In, |
1148 | ParseToken::Key("a" .to_string()), |
1149 | ParseToken::Array, |
1150 | ParseToken::Relative, |
1151 | ParseToken::In, |
1152 | ParseToken::Key("e" .to_string()), |
1153 | ParseToken::Bool(true), |
1154 | ParseToken::Filter(FilterToken::Equal), |
1155 | ParseToken::ArrayEof |
1156 | ]) |
1157 | ); |
1158 | |
1159 | assert_eq!( |
1160 | run(r#"$[?(@ > 1)]"# ), |
1161 | Ok(vec![ |
1162 | ParseToken::Absolute, |
1163 | ParseToken::Array, |
1164 | ParseToken::Relative, |
1165 | ParseToken::Number(1_f64), |
1166 | ParseToken::Filter(FilterToken::Greater), |
1167 | ParseToken::ArrayEof |
1168 | ]) |
1169 | ); |
1170 | |
1171 | assert_eq!( |
1172 | run("$[:]" ), |
1173 | Ok(vec![ |
1174 | ParseToken::Absolute, |
1175 | ParseToken::Array, |
1176 | ParseToken::Range(None, None, None), |
1177 | ParseToken::ArrayEof |
1178 | ]) |
1179 | ); |
1180 | |
1181 | assert_eq!( |
1182 | run(r#"$['single\'quote']"# ), |
1183 | Ok(vec![ |
1184 | ParseToken::Absolute, |
1185 | ParseToken::Array, |
1186 | ParseToken::Key("single'quote" .to_string()), |
1187 | ParseToken::ArrayEof |
1188 | ]) |
1189 | ); |
1190 | |
1191 | assert_eq!( |
1192 | run(r#"$["single\"quote"]"# ), |
1193 | Ok(vec![ |
1194 | ParseToken::Absolute, |
1195 | ParseToken::Array, |
1196 | ParseToken::Key(r#"single"quote"# .to_string()), |
1197 | ParseToken::ArrayEof |
1198 | ]) |
1199 | ); |
1200 | } |
1201 | |
1202 | #[test ] |
1203 | fn parse_array_float() { |
1204 | setup(); |
1205 | |
1206 | assert_eq!( |
1207 | run("$[?(1.1<2.1)]" ), |
1208 | Ok(vec![ |
1209 | ParseToken::Absolute, |
1210 | ParseToken::Array, |
1211 | ParseToken::Number(1.1), |
1212 | ParseToken::Number(2.1), |
1213 | ParseToken::Filter(FilterToken::Little), |
1214 | ParseToken::ArrayEof |
1215 | ]) |
1216 | ); |
1217 | |
1218 | if run("$[1.1]" ).is_ok() { |
1219 | panic!(); |
1220 | } |
1221 | |
1222 | if run("$[?(1.1<.2)]" ).is_ok() { |
1223 | panic!(); |
1224 | } |
1225 | |
1226 | if run("$[?(1.1<2.)]" ).is_ok() { |
1227 | panic!(); |
1228 | } |
1229 | |
1230 | if run("$[?(1.1<2.a)]" ).is_ok() { |
1231 | panic!(); |
1232 | } |
1233 | } |
1234 | } |
1235 | |
1236 | #[cfg (test)] |
1237 | mod tokenizer_tests { |
1238 | use parser::tokenizer::{Token, TokenError, TokenReader, Tokenizer}; |
1239 | |
1240 | fn setup() { |
1241 | let _ = env_logger::try_init(); |
1242 | } |
1243 | |
1244 | fn collect_token(input: &str) -> (Vec<Token>, Option<TokenError>) { |
1245 | let mut tokenizer = Tokenizer::new(input); |
1246 | let mut vec = vec![]; |
1247 | loop { |
1248 | match tokenizer.next_token() { |
1249 | Ok(t) => vec.push(t), |
1250 | Err(e) => return (vec, Some(e)), |
1251 | } |
1252 | } |
1253 | } |
1254 | |
1255 | fn run(input: &str, expected: (Vec<Token>, Option<TokenError>)) { |
1256 | let (vec, err) = collect_token(input); |
1257 | assert_eq!((vec, err), expected, " \"{}\"" , input); |
1258 | } |
1259 | |
1260 | #[test ] |
1261 | fn peek() { |
1262 | let mut tokenizer = TokenReader::new("$.a" ); |
1263 | match tokenizer.next_token() { |
1264 | Ok(t) => assert_eq!(Token::Absolute(0), t), |
1265 | _ => panic!(), |
1266 | } |
1267 | |
1268 | match tokenizer.peek_token() { |
1269 | Ok(t) => assert_eq!(&Token::Dot(1), t), |
1270 | _ => panic!(), |
1271 | } |
1272 | |
1273 | match tokenizer.peek_token() { |
1274 | Ok(t) => assert_eq!(&Token::Dot(1), t), |
1275 | _ => panic!(), |
1276 | } |
1277 | |
1278 | match tokenizer.next_token() { |
1279 | Ok(t) => assert_eq!(Token::Dot(1), t), |
1280 | _ => panic!(), |
1281 | } |
1282 | } |
1283 | |
1284 | #[test ] |
1285 | fn token() { |
1286 | setup(); |
1287 | |
1288 | run( |
1289 | "$.01.a" , |
1290 | ( |
1291 | vec![ |
1292 | Token::Absolute(0), |
1293 | Token::Dot(1), |
1294 | Token::Key(2, "01" .to_string()), |
1295 | Token::Dot(4), |
1296 | Token::Key(5, "a" .to_string()), |
1297 | ], |
1298 | Some(TokenError::Eof), |
1299 | ), |
1300 | ); |
1301 | |
1302 | run( |
1303 | "$. []" , |
1304 | ( |
1305 | vec![ |
1306 | Token::Absolute(0), |
1307 | Token::Dot(1), |
1308 | Token::Whitespace(2, 2), |
1309 | Token::OpenArray(5), |
1310 | Token::CloseArray(6), |
1311 | ], |
1312 | Some(TokenError::Eof), |
1313 | ), |
1314 | ); |
1315 | |
1316 | run( |
1317 | "$.." , |
1318 | ( |
1319 | vec![Token::Absolute(0), Token::Dot(1), Token::Dot(2)], |
1320 | Some(TokenError::Eof), |
1321 | ), |
1322 | ); |
1323 | |
1324 | run( |
1325 | "$..ab" , |
1326 | ( |
1327 | vec![ |
1328 | Token::Absolute(0), |
1329 | Token::Dot(1), |
1330 | Token::Dot(2), |
1331 | Token::Key(3, "ab" .to_string()), |
1332 | ], |
1333 | Some(TokenError::Eof), |
1334 | ), |
1335 | ); |
1336 | |
1337 | run( |
1338 | "$..가 [" , |
1339 | ( |
1340 | vec![ |
1341 | Token::Absolute(0), |
1342 | Token::Dot(1), |
1343 | Token::Dot(2), |
1344 | Token::Key(3, "가" .to_string()), |
1345 | Token::Whitespace(6, 0), |
1346 | Token::OpenArray(7), |
1347 | ], |
1348 | Some(TokenError::Eof), |
1349 | ), |
1350 | ); |
1351 | |
1352 | run( |
1353 | "[-1, 2 ]" , |
1354 | ( |
1355 | vec![ |
1356 | Token::OpenArray(0), |
1357 | Token::Key(1, "-1" .to_string()), |
1358 | Token::Comma(3), |
1359 | Token::Whitespace(4, 0), |
1360 | Token::Key(5, "2" .to_string()), |
1361 | Token::Whitespace(6, 0), |
1362 | Token::CloseArray(7), |
1363 | ], |
1364 | Some(TokenError::Eof), |
1365 | ), |
1366 | ); |
1367 | |
1368 | run( |
1369 | "[ 1 2 , 3 \"abc \" : -10 ]" , |
1370 | ( |
1371 | vec![ |
1372 | Token::OpenArray(0), |
1373 | Token::Whitespace(1, 0), |
1374 | Token::Key(2, "1" .to_string()), |
1375 | Token::Whitespace(3, 0), |
1376 | Token::Key(4, "2" .to_string()), |
1377 | Token::Whitespace(5, 0), |
1378 | Token::Comma(6), |
1379 | Token::Whitespace(7, 0), |
1380 | Token::Key(8, "3" .to_string()), |
1381 | Token::Whitespace(9, 0), |
1382 | Token::DoubleQuoted(10, "abc" .to_string()), |
1383 | Token::Whitespace(15, 0), |
1384 | Token::Split(16), |
1385 | Token::Whitespace(17, 0), |
1386 | Token::Key(18, "-10" .to_string()), |
1387 | Token::Whitespace(21, 0), |
1388 | Token::CloseArray(22), |
1389 | ], |
1390 | Some(TokenError::Eof), |
1391 | ), |
1392 | ); |
1393 | |
1394 | run( |
1395 | "?(@.a가 <41.01)" , |
1396 | ( |
1397 | vec![ |
1398 | Token::Question(0), |
1399 | Token::OpenParenthesis(1), |
1400 | Token::At(2), |
1401 | Token::Dot(3), |
1402 | Token::Key(4, "a가" .to_string()), |
1403 | Token::Whitespace(8, 0), |
1404 | Token::Little(9), |
1405 | Token::Key(10, "41" .to_string()), |
1406 | Token::Dot(12), |
1407 | Token::Key(13, "01" .to_string()), |
1408 | Token::CloseParenthesis(15), |
1409 | ], |
1410 | Some(TokenError::Eof), |
1411 | ), |
1412 | ); |
1413 | |
1414 | run( |
1415 | "?(@.a <4a.01)" , |
1416 | ( |
1417 | vec![ |
1418 | Token::Question(0), |
1419 | Token::OpenParenthesis(1), |
1420 | Token::At(2), |
1421 | Token::Dot(3), |
1422 | Token::Key(4, "a" .to_string()), |
1423 | Token::Whitespace(5, 0), |
1424 | Token::Little(6), |
1425 | Token::Key(7, "4a" .to_string()), |
1426 | Token::Dot(9), |
1427 | Token::Key(10, "01" .to_string()), |
1428 | Token::CloseParenthesis(12), |
1429 | ], |
1430 | Some(TokenError::Eof), |
1431 | ), |
1432 | ); |
1433 | |
1434 | run( |
1435 | "?($.c>@.d)" , |
1436 | ( |
1437 | vec![ |
1438 | Token::Question(0), |
1439 | Token::OpenParenthesis(1), |
1440 | Token::Absolute(2), |
1441 | Token::Dot(3), |
1442 | Token::Key(4, "c" .to_string()), |
1443 | Token::Greater(5), |
1444 | Token::At(6), |
1445 | Token::Dot(7), |
1446 | Token::Key(8, "d" .to_string()), |
1447 | Token::CloseParenthesis(9), |
1448 | ], |
1449 | Some(TokenError::Eof), |
1450 | ), |
1451 | ); |
1452 | |
1453 | run( |
1454 | "$[:]" , |
1455 | ( |
1456 | vec![ |
1457 | Token::Absolute(0), |
1458 | Token::OpenArray(1), |
1459 | Token::Split(2), |
1460 | Token::CloseArray(3), |
1461 | ], |
1462 | Some(TokenError::Eof), |
1463 | ), |
1464 | ); |
1465 | |
1466 | run( |
1467 | r#"$['single\'quote']"# , |
1468 | ( |
1469 | vec![ |
1470 | Token::Absolute(0), |
1471 | Token::OpenArray(1), |
1472 | Token::SingleQuoted(2, "single \'quote" .to_string()), |
1473 | Token::CloseArray(17), |
1474 | ], |
1475 | Some(TokenError::Eof), |
1476 | ), |
1477 | ); |
1478 | |
1479 | run( |
1480 | r#"$['single\'1','single\'2']"# , |
1481 | ( |
1482 | vec![ |
1483 | Token::Absolute(0), |
1484 | Token::OpenArray(1), |
1485 | Token::SingleQuoted(2, "single \'1" .to_string()), |
1486 | Token::Comma(13), |
1487 | Token::SingleQuoted(14, "single \'2" .to_string()), |
1488 | Token::CloseArray(25), |
1489 | ], |
1490 | Some(TokenError::Eof), |
1491 | ), |
1492 | ); |
1493 | |
1494 | run( |
1495 | r#"$["double\"quote"]"# , |
1496 | ( |
1497 | vec![ |
1498 | Token::Absolute(0), |
1499 | Token::OpenArray(1), |
1500 | Token::DoubleQuoted(2, "double \"quote" .to_string()), |
1501 | Token::CloseArray(17), |
1502 | ], |
1503 | Some(TokenError::Eof), |
1504 | ), |
1505 | ); |
1506 | } |
1507 | } |
1508 | |