1use std::fmt;
7
8#[derive(Debug, Clone, PartialEq, serde::Serialize)]
10pub struct Filter {
11 pub expr: Expr,
13}
14
15#[derive(Debug, Clone, PartialEq, serde::Serialize)]
17pub enum Expr {
18 Identity,
20
21 FieldAccess {
23 base: Box<Expr>,
25 fields: Vec<String>,
27 },
28
29 ArrayAccess {
31 array: Box<Expr>,
33 index: Box<Expr>,
35 },
36
37 ArraySlice {
39 array: Box<Expr>,
41 start: Option<Box<Expr>>,
43 end: Option<Box<Expr>>,
45 },
46
47 ArrayIteration(Box<Expr>),
49
50 FunctionCall {
52 name: String,
54 args: Vec<Expr>,
56 },
57
58 BinaryOp {
60 left: Box<Expr>,
62 op: BinaryOperator,
64 right: Box<Expr>,
66 },
67
68 UnaryOp {
70 op: UnaryOperator,
72 expr: Box<Expr>,
74 },
75
76 Assignment {
78 op: AssignmentOperator,
80 target: Box<Expr>,
82 value: Box<Expr>,
84 },
85
86 Object {
88 pairs: Vec<ObjectEntry>,
90 },
91
92 Array(Vec<Expr>),
94
95 Literal(Literal),
97
98 Identifier(String),
100
101 Variable(String),
103
104 Paren(Box<Expr>),
106
107 Pipeline(Vec<Expr>),
109
110 If {
112 condition: Box<Expr>,
114 then_branch: Box<Expr>,
116 else_branch: Box<Expr>,
118 },
119
120 Sequence(Vec<Expr>),
122}
123
124#[derive(Debug, Clone, PartialEq, serde::Serialize)]
126pub enum BinaryOperator {
127 Add,
129 Sub,
131 Mul,
133 Div,
135 Gt,
137 Lt,
139 Eq,
141 Ne,
143 Ge,
145 Le,
147 And,
149 Or,
151}
152
153#[derive(Debug, Clone, PartialEq, serde::Serialize)]
155pub enum AssignmentOperator {
156 AddAssign,
158 UpdateAssign,
160}
161
162#[derive(Debug, Clone, PartialEq, serde::Serialize)]
164pub enum UnaryOperator {
165 Not,
167 Del,
169}
170
171#[derive(Debug, Clone, PartialEq, serde::Serialize)]
173pub enum ObjectEntry {
174 KeyValue {
176 key: String,
178 value: Expr,
180 },
181 Shorthand(String),
183}
184
185#[derive(Debug, Clone, PartialEq, serde::Serialize)]
187pub struct OrderBy {
188 pub column: String,
190 pub direction: OrderDirection,
192}
193
194#[derive(Debug, Clone, PartialEq, serde::Serialize)]
196pub enum OrderDirection {
197 Asc,
199 Desc,
201}
202
203#[derive(Debug, Clone, PartialEq, serde::Serialize)]
205pub enum Literal {
206 Int(i64),
208 BigInt(num_bigint::BigInt),
210 Float(f64),
212 String(String),
214 Bool(bool),
216 Null,
218}
219
220impl fmt::Display for Filter {
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 write!(f, "{}", self.expr)
223 }
224}
225
226impl fmt::Display for Expr {
227 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
228 match self {
229 Expr::Identity => write!(f, "."),
230
231 Expr::FieldAccess { base, fields } => {
232 if matches!(**base, Expr::Identity) {
233 write!(f, ".")?;
234 } else {
235 write!(f, "{}", base)?;
236 }
237 for (i, field) in fields.iter().enumerate() {
238 if i > 0 || !matches!(**base, Expr::Identity) {
239 write!(f, ".")?;
240 }
241 write!(f, "{}", field)?;
242 }
243 Ok(())
244 }
245 Expr::ArrayAccess { array, index } => write!(f, "{}[{}]", array, index),
246 Expr::ArraySlice { array, start, end } => {
247 write!(f, "{}[", array)?;
248 if let Some(start) = start {
249 write!(f, "{}", start)?;
250 }
251 write!(f, ":")?;
252 if let Some(end) = end {
253 write!(f, "{}", end)?;
254 }
255 write!(f, "]")
256 }
257 Expr::ArrayIteration(expr) => write!(f, "{}[]", expr),
258 Expr::FunctionCall { name, args } => {
259 write!(f, "{}(", name)?;
260 for (i, arg) in args.iter().enumerate() {
261 if i > 0 {
262 write!(f, ", ")?;
263 }
264 write!(f, "{}", arg)?;
265 }
266 write!(f, ")")
267 }
268 Expr::BinaryOp { left, op, right } => write!(f, "{} {} {}", left, op, right),
269 Expr::UnaryOp { op, expr } => write!(f, "{} {}", op, expr),
270 Expr::Assignment { op, target, value } => write!(f, "{} {} {}", target, op, value),
271 Expr::Object { pairs } => {
272 write!(f, "{{")?;
273 for (i, pair) in pairs.iter().enumerate() {
274 if i > 0 {
275 write!(f, ", ")?;
276 }
277 match pair {
278 ObjectEntry::KeyValue { key, value } => write!(f, "{}: {}", key, value)?,
279 ObjectEntry::Shorthand(key) => write!(f, "{}", key)?,
280 }
281 }
282 write!(f, "}}")
283 }
284 Expr::Array(elements) => {
285 write!(f, "[")?;
286 for (i, elem) in elements.iter().enumerate() {
287 if i > 0 {
288 write!(f, ", ")?;
289 }
290 write!(f, "{}", elem)?;
291 }
292 write!(f, "]")
293 }
294 Expr::Literal(lit) => write!(f, "{}", lit),
295 Expr::Identifier(name) => write!(f, "{}", name),
296 Expr::Variable(name) => write!(f, "${}", name),
297 Expr::Paren(expr) => write!(f, "({})", expr),
298 Expr::Pipeline(exprs) => {
299 for (i, expr) in exprs.iter().enumerate() {
300 if i > 0 {
301 write!(f, " | ")?;
302 }
303 write!(f, "{}", expr)?;
304 }
305 Ok(())
306 }
307 Expr::If {
308 condition,
309 then_branch,
310 else_branch,
311 } => {
312 write!(
313 f,
314 "if {} then {} else {} end",
315 condition, then_branch, else_branch
316 )
317 }
318 Expr::Sequence(exprs) => {
319 for (i, expr) in exprs.iter().enumerate() {
320 if i > 0 {
321 write!(f, ", ")?;
322 }
323 write!(f, "{}", expr)?;
324 }
325 Ok(())
326 }
327 }
328 }
329}
330
331impl fmt::Display for BinaryOperator {
332 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
333 match self {
334 BinaryOperator::Add => write!(f, "+"),
335 BinaryOperator::Sub => write!(f, "-"),
336 BinaryOperator::Mul => write!(f, "*"),
337 BinaryOperator::Div => write!(f, "/"),
338 BinaryOperator::Gt => write!(f, ">"),
339 BinaryOperator::Lt => write!(f, "<"),
340 BinaryOperator::Eq => write!(f, "=="),
341 BinaryOperator::Ne => write!(f, "!="),
342 BinaryOperator::Ge => write!(f, ">="),
343 BinaryOperator::Le => write!(f, "<="),
344 BinaryOperator::And => write!(f, "and"),
345 BinaryOperator::Or => write!(f, "or"),
346 }
347 }
348}
349
350impl fmt::Display for UnaryOperator {
351 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352 match self {
353 UnaryOperator::Not => write!(f, "not"),
354 UnaryOperator::Del => write!(f, "del"),
355 }
356 }
357}
358
359impl fmt::Display for AssignmentOperator {
360 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361 match self {
362 AssignmentOperator::AddAssign => write!(f, "+="),
363 AssignmentOperator::UpdateAssign => write!(f, "|="),
364 }
365 }
366}
367
368impl fmt::Display for OrderDirection {
369 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
370 match self {
371 OrderDirection::Asc => write!(f, "asc"),
372 OrderDirection::Desc => write!(f, "desc"),
373 }
374 }
375}
376
377impl fmt::Display for Literal {
378 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
379 match self {
380 Literal::Int(i) => write!(f, "{}", i),
381 Literal::BigInt(bi) => write!(f, "{}", bi),
382 Literal::Float(fl) => write!(f, "{}", fl),
383 Literal::String(s) => write!(f, "\"{}\"", s),
384 Literal::Bool(b) => write!(f, "{}", b),
385 Literal::Null => write!(f, "null"),
386 }
387 }
388}
389
390#[cfg(test)]
391mod tests {
392 use super::*;
393 use num_bigint::BigInt;
394
395 #[test]
396 fn test_literal_display() {
397 assert_eq!(format!("{}", Literal::Int(42)), "42");
398 assert_eq!(format!("{}", Literal::Int(-42)), "-42");
399 assert_eq!(
400 format!("{}", Literal::BigInt(BigInt::from(123456789))),
401 "123456789"
402 );
403 assert_eq!(format!("{}", Literal::Float(3.14)), "3.14");
404 assert_eq!(format!("{}", Literal::Float(-3.14)), "-3.14");
405 assert_eq!(
406 format!("{}", Literal::String("hello".to_string())),
407 "\"hello\""
408 );
409 assert_eq!(
410 format!("{}", Literal::String("with \"quotes\"".to_string())),
411 "\"with \"quotes\"\""
412 );
413 assert_eq!(format!("{}", Literal::Bool(true)), "true");
414 assert_eq!(format!("{}", Literal::Bool(false)), "false");
415 assert_eq!(format!("{}", Literal::Null), "null");
416 }
417
418 #[test]
419 fn test_binary_operator_display() {
420 assert_eq!(format!("{}", BinaryOperator::Add), "+");
421 assert_eq!(format!("{}", BinaryOperator::Sub), "-");
422 assert_eq!(format!("{}", BinaryOperator::Mul), "*");
423 assert_eq!(format!("{}", BinaryOperator::Div), "/");
424 assert_eq!(format!("{}", BinaryOperator::Gt), ">");
425 assert_eq!(format!("{}", BinaryOperator::Lt), "<");
426 assert_eq!(format!("{}", BinaryOperator::Eq), "==");
427 assert_eq!(format!("{}", BinaryOperator::Ne), "!=");
428 assert_eq!(format!("{}", BinaryOperator::Ge), ">=");
429 assert_eq!(format!("{}", BinaryOperator::Le), "<=");
430 assert_eq!(format!("{}", BinaryOperator::And), "and");
431 assert_eq!(format!("{}", BinaryOperator::Or), "or");
432 }
433
434 #[test]
435 fn test_unary_operator_display() {
436 assert_eq!(format!("{}", UnaryOperator::Not), "not");
437 assert_eq!(format!("{}", UnaryOperator::Del), "del");
438 }
439
440 #[test]
441 fn test_assignment_operator_display() {
442 assert_eq!(format!("{}", AssignmentOperator::AddAssign), "+=");
443 assert_eq!(format!("{}", AssignmentOperator::UpdateAssign), "|=");
444 }
445
446 #[test]
447 fn test_order_direction_display() {
448 assert_eq!(format!("{}", OrderDirection::Asc), "asc");
449 assert_eq!(format!("{}", OrderDirection::Desc), "desc");
450 }
451
452 #[test]
453 fn test_expr_display_identity() {
454 let expr = Expr::Identity;
455 assert_eq!(format!("{}", expr), ".");
456 }
457
458 #[test]
459 fn test_expr_display_field_access() {
460 let expr = Expr::FieldAccess {
462 base: Box::new(Expr::Identity),
463 fields: vec!["name".to_string()],
464 };
465 assert_eq!(format!("{}", expr), ".name");
466
467 let expr = Expr::FieldAccess {
469 base: Box::new(Expr::Identity),
470 fields: vec!["user".to_string(), "name".to_string()],
471 };
472 assert_eq!(format!("{}", expr), ".user.name");
473
474 let expr = Expr::FieldAccess {
476 base: Box::new(Expr::Identifier("obj".to_string())),
477 fields: vec!["field".to_string()],
478 };
479 assert_eq!(format!("{}", expr), "obj.field");
480 }
481
482 #[test]
483 fn test_expr_display_array_access() {
484 let expr = Expr::ArrayAccess {
485 array: Box::new(Expr::Identity),
486 index: Box::new(Expr::Literal(Literal::Int(0))),
487 };
488 assert_eq!(format!("{}", expr), ".[0]");
489 }
490
491 #[test]
492 fn test_expr_display_array_slice() {
493 let expr = Expr::ArraySlice {
495 array: Box::new(Expr::Identity),
496 start: None,
497 end: None,
498 };
499 assert_eq!(format!("{}", expr), ".[:]");
500
501 let expr = Expr::ArraySlice {
503 array: Box::new(Expr::Identity),
504 start: Some(Box::new(Expr::Literal(Literal::Int(1)))),
505 end: None,
506 };
507 assert_eq!(format!("{}", expr), ".[1:]");
508
509 let expr = Expr::ArraySlice {
511 array: Box::new(Expr::Identity),
512 start: None,
513 end: Some(Box::new(Expr::Literal(Literal::Int(5)))),
514 };
515 assert_eq!(format!("{}", expr), ".[:5]");
516
517 let expr = Expr::ArraySlice {
519 array: Box::new(Expr::Identity),
520 start: Some(Box::new(Expr::Literal(Literal::Int(1)))),
521 end: Some(Box::new(Expr::Literal(Literal::Int(5)))),
522 };
523 assert_eq!(format!("{}", expr), ".[1:5]");
524 }
525
526 #[test]
527 fn test_expr_display_array_iteration() {
528 let expr = Expr::ArrayIteration(Box::new(Expr::Identity));
529 assert_eq!(format!("{}", expr), ".[]");
530 }
531
532 #[test]
533 fn test_expr_display_function_call() {
534 let expr = Expr::FunctionCall {
536 name: "length".to_string(),
537 args: vec![],
538 };
539 assert_eq!(format!("{}", expr), "length()");
540
541 let expr = Expr::FunctionCall {
543 name: "map".to_string(),
544 args: vec![Expr::Identity],
545 };
546 assert_eq!(format!("{}", expr), "map(.)");
547
548 let expr = Expr::FunctionCall {
550 name: "add".to_string(),
551 args: vec![
552 Expr::Literal(Literal::Int(1)),
553 Expr::Literal(Literal::Int(2)),
554 ],
555 };
556 assert_eq!(format!("{}", expr), "add(1, 2)");
557 }
558
559 #[test]
560 fn test_expr_display_binary_op() {
561 let expr = Expr::BinaryOp {
562 left: Box::new(Expr::Literal(Literal::Int(1))),
563 op: BinaryOperator::Add,
564 right: Box::new(Expr::Literal(Literal::Int(2))),
565 };
566 assert_eq!(format!("{}", expr), "1 + 2");
567 }
568
569 #[test]
570 fn test_expr_display_unary_op() {
571 let expr = Expr::UnaryOp {
572 op: UnaryOperator::Not,
573 expr: Box::new(Expr::Literal(Literal::Bool(true))),
574 };
575 assert_eq!(format!("{}", expr), "not true");
576 }
577
578 #[test]
579 fn test_expr_display_assignment() {
580 let expr = Expr::Assignment {
581 op: AssignmentOperator::AddAssign,
582 target: Box::new(Expr::FieldAccess {
583 base: Box::new(Expr::Identity),
584 fields: vec!["salary".to_string()],
585 }),
586 value: Box::new(Expr::Literal(Literal::Int(5000))),
587 };
588 assert_eq!(format!("{}", expr), ".salary += 5000");
589 }
590
591 #[test]
592 fn test_expr_display_object() {
593 let expr = Expr::Object { pairs: vec![] };
595 assert_eq!(format!("{}", expr), "{}");
596
597 let expr = Expr::Object {
599 pairs: vec![ObjectEntry::Shorthand("name".to_string())],
600 };
601 assert_eq!(format!("{}", expr), "{name}");
602
603 let expr = Expr::Object {
605 pairs: vec![ObjectEntry::KeyValue {
606 key: "age".to_string(),
607 value: Expr::Literal(Literal::Int(30)),
608 }],
609 };
610 assert_eq!(format!("{}", expr), "{age: 30}");
611
612 let expr = Expr::Object {
614 pairs: vec![
615 ObjectEntry::Shorthand("name".to_string()),
616 ObjectEntry::KeyValue {
617 key: "age".to_string(),
618 value: Expr::Literal(Literal::Int(30)),
619 },
620 ],
621 };
622 assert_eq!(format!("{}", expr), "{name, age: 30}");
623 }
624
625 #[test]
626 fn test_expr_display_array() {
627 let expr = Expr::Array(vec![]);
629 assert_eq!(format!("{}", expr), "[]");
630
631 let expr = Expr::Array(vec![
633 Expr::Literal(Literal::Int(1)),
634 Expr::Literal(Literal::Int(2)),
635 Expr::Literal(Literal::Int(3)),
636 ]);
637 assert_eq!(format!("{}", expr), "[1, 2, 3]");
638 }
639
640 #[test]
641 fn test_expr_display_literal() {
642 let expr = Expr::Literal(Literal::String("hello".to_string()));
643 assert_eq!(format!("{}", expr), "\"hello\"");
644 }
645
646 #[test]
647 fn test_expr_display_identifier() {
648 let expr = Expr::Identifier("func".to_string());
649 assert_eq!(format!("{}", expr), "func");
650 }
651
652 #[test]
653 fn test_expr_display_variable() {
654 let expr = Expr::Variable("config".to_string());
655 assert_eq!(format!("{}", expr), "$config");
656 }
657
658 #[test]
659 fn test_expr_display_paren() {
660 let expr = Expr::Paren(Box::new(Expr::Literal(Literal::Int(42))));
661 assert_eq!(format!("{}", expr), "(42)");
662 }
663
664 #[test]
665 fn test_expr_display_pipeline() {
666 let expr = Expr::Pipeline(vec![
667 Expr::Identity,
668 Expr::FunctionCall {
669 name: "map".to_string(),
670 args: vec![Expr::FieldAccess {
671 base: Box::new(Expr::Identity),
672 fields: vec!["name".to_string()],
673 }],
674 },
675 ]);
676 assert_eq!(format!("{}", expr), ". | map(.name)");
677 }
678
679 #[test]
680 fn test_expr_display_if() {
681 let expr = Expr::If {
682 condition: Box::new(Expr::Literal(Literal::Bool(true))),
683 then_branch: Box::new(Expr::Literal(Literal::Int(1))),
684 else_branch: Box::new(Expr::Literal(Literal::Int(0))),
685 };
686 assert_eq!(format!("{}", expr), "if true then 1 else 0 end");
687 }
688
689 #[test]
690 fn test_expr_display_sequence() {
691 let expr = Expr::Sequence(vec![
692 Expr::FieldAccess {
693 base: Box::new(Expr::Identity),
694 fields: vec!["name".to_string()],
695 },
696 Expr::FieldAccess {
697 base: Box::new(Expr::Identity),
698 fields: vec!["age".to_string()],
699 },
700 ]);
701 assert_eq!(format!("{}", expr), ".name, .age");
702 }
703
704 #[test]
705 fn test_filter_display() {
706 let filter = Filter {
707 expr: Expr::Identity,
708 };
709 assert_eq!(format!("{}", filter), ".");
710 }
711
712 #[test]
713 fn test_partial_eq() {
714 let expr1 = Expr::Literal(Literal::Int(42));
716 let expr2 = Expr::Literal(Literal::Int(42));
717 assert_eq!(expr1, expr2);
718
719 let expr3 = Expr::Literal(Literal::Int(43));
721 assert_ne!(expr1, expr3);
722
723 let obj1 = Expr::Object {
725 pairs: vec![ObjectEntry::Shorthand("name".to_string())],
726 };
727 let obj2 = Expr::Object {
728 pairs: vec![ObjectEntry::Shorthand("name".to_string())],
729 };
730 assert_eq!(obj1, obj2);
731
732 let obj3 = Expr::Object {
733 pairs: vec![ObjectEntry::Shorthand("age".to_string())],
734 };
735 assert_ne!(obj1, obj3);
736 }
737
738 #[test]
739 fn test_clone() {
740 let original = Expr::BinaryOp {
741 left: Box::new(Expr::Literal(Literal::Int(1))),
742 op: BinaryOperator::Add,
743 right: Box::new(Expr::Literal(Literal::Int(2))),
744 };
745 let cloned = original.clone();
746 assert_eq!(original, cloned);
747 }
748
749 #[test]
750 fn test_serde_serialize() {
751 let expr = Expr::Literal(Literal::Int(42));
752 let serialized = serde_json::to_string(&expr).unwrap();
753 assert!(serialized.contains("42"));
755 }
756}