1use serde::{Deserialize, Serialize};
14use smol_str::SmolStr;
15
16use crate::{
17 AggExpr, BinOp, Direction, Expr, LabelSet, ListPredKind, NodeSpec, OpId, OrderKey, Projection,
18 ReadOp, RelLength, RelSpec, SortDir, UnaryOp, UnionKind, VarId, WriteOp,
19};
20
21impl Serialize for VarId {
24 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
25 s.serialize_u32(self.0)
26 }
27}
28
29impl<'de> Deserialize<'de> for VarId {
30 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
31 u32::deserialize(d).map(VarId)
32 }
33}
34
35impl Serialize for OpId {
36 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
37 s.serialize_u32(self.0)
38 }
39}
40
41impl<'de> Deserialize<'de> for OpId {
42 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
43 u32::deserialize(d).map(OpId)
44 }
45}
46
47impl Serialize for LabelSet {
50 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
51 self.0.serialize(s)
52 }
53}
54
55impl<'de> Deserialize<'de> for LabelSet {
56 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
57 Vec::<SmolStr>::deserialize(d).map(LabelSet)
58 }
59}
60
61impl Serialize for Direction {
64 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
65 let tag = match self {
66 Direction::Outgoing => "outgoing",
67 Direction::Incoming => "incoming",
68 Direction::Undirected => "undirected",
69 };
70 s.serialize_str(tag)
71 }
72}
73
74impl<'de> Deserialize<'de> for Direction {
75 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
76 let s = String::deserialize(d)?;
77 match s.as_str() {
78 "outgoing" => Ok(Direction::Outgoing),
79 "incoming" => Ok(Direction::Incoming),
80 "undirected" => Ok(Direction::Undirected),
81 other => Err(serde::de::Error::unknown_variant(
82 other,
83 &["outgoing", "incoming", "undirected"],
84 )),
85 }
86 }
87}
88
89#[derive(Serialize, Deserialize)]
92#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
93enum RelLengthSer {
94 Single,
95 Variable { min: Option<u64>, max: Option<u64> },
96}
97
98impl Serialize for RelLength {
99 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
100 let proxy = match self {
101 RelLength::Single => RelLengthSer::Single,
102 RelLength::Variable { min, max } => RelLengthSer::Variable {
103 min: *min,
104 max: *max,
105 },
106 };
107 proxy.serialize(s)
108 }
109}
110
111impl<'de> Deserialize<'de> for RelLength {
112 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
113 match RelLengthSer::deserialize(d)? {
114 RelLengthSer::Single => Ok(RelLength::Single),
115 RelLengthSer::Variable { min, max } => Ok(RelLength::Variable { min, max }),
116 }
117 }
118}
119
120impl Serialize for UnionKind {
123 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
124 let tag = match self {
125 UnionKind::All => "all",
126 UnionKind::Distinct => "distinct",
127 };
128 s.serialize_str(tag)
129 }
130}
131
132impl<'de> Deserialize<'de> for UnionKind {
133 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
134 let s = String::deserialize(d)?;
135 match s.as_str() {
136 "all" => Ok(UnionKind::All),
137 "distinct" => Ok(UnionKind::Distinct),
138 other => Err(serde::de::Error::unknown_variant(
139 other,
140 &["all", "distinct"],
141 )),
142 }
143 }
144}
145
146impl Serialize for SortDir {
149 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
150 let tag = match self {
151 SortDir::Asc => "asc",
152 SortDir::Desc => "desc",
153 };
154 s.serialize_str(tag)
155 }
156}
157
158impl<'de> Deserialize<'de> for SortDir {
159 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
160 let s = String::deserialize(d)?;
161 match s.as_str() {
162 "asc" => Ok(SortDir::Asc),
163 "desc" => Ok(SortDir::Desc),
164 other => Err(serde::de::Error::unknown_variant(other, &["asc", "desc"])),
165 }
166 }
167}
168
169impl Serialize for BinOp {
172 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
173 let tag = match self {
174 BinOp::Add => "add",
175 BinOp::Sub => "sub",
176 BinOp::Mul => "mul",
177 BinOp::Div => "div",
178 BinOp::Mod => "mod",
179 BinOp::Pow => "pow",
180 BinOp::Eq => "eq",
181 BinOp::Neq => "neq",
182 BinOp::Lt => "lt",
183 BinOp::Le => "le",
184 BinOp::Gt => "gt",
185 BinOp::Ge => "ge",
186 BinOp::And => "and",
187 BinOp::Or => "or",
188 BinOp::Xor => "xor",
189 BinOp::In => "in",
190 BinOp::StartsWith => "starts_with",
191 BinOp::EndsWith => "ends_with",
192 BinOp::Contains => "contains",
193 BinOp::RegexMatch => "regex_match",
194 BinOp::Concat => "concat",
195 };
196 s.serialize_str(tag)
197 }
198}
199
200impl<'de> Deserialize<'de> for BinOp {
201 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
202 let s = String::deserialize(d)?;
203 match s.as_str() {
204 "add" => Ok(BinOp::Add),
205 "sub" => Ok(BinOp::Sub),
206 "mul" => Ok(BinOp::Mul),
207 "div" => Ok(BinOp::Div),
208 "mod" => Ok(BinOp::Mod),
209 "pow" => Ok(BinOp::Pow),
210 "eq" => Ok(BinOp::Eq),
211 "neq" => Ok(BinOp::Neq),
212 "lt" => Ok(BinOp::Lt),
213 "le" => Ok(BinOp::Le),
214 "gt" => Ok(BinOp::Gt),
215 "ge" => Ok(BinOp::Ge),
216 "and" => Ok(BinOp::And),
217 "or" => Ok(BinOp::Or),
218 "xor" => Ok(BinOp::Xor),
219 "in" => Ok(BinOp::In),
220 "starts_with" => Ok(BinOp::StartsWith),
221 "ends_with" => Ok(BinOp::EndsWith),
222 "contains" => Ok(BinOp::Contains),
223 "regex_match" => Ok(BinOp::RegexMatch),
224 "concat" => Ok(BinOp::Concat),
225 other => Err(serde::de::Error::unknown_variant(
226 other,
227 &[
228 "add",
229 "sub",
230 "mul",
231 "div",
232 "mod",
233 "pow",
234 "eq",
235 "neq",
236 "lt",
237 "le",
238 "gt",
239 "ge",
240 "and",
241 "or",
242 "xor",
243 "in",
244 "starts_with",
245 "ends_with",
246 "contains",
247 "regex_match",
248 "concat",
249 ],
250 )),
251 }
252 }
253}
254
255impl Serialize for UnaryOp {
258 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
259 let tag = match self {
260 UnaryOp::Neg => "neg",
261 UnaryOp::Not => "not",
262 };
263 s.serialize_str(tag)
264 }
265}
266
267impl<'de> Deserialize<'de> for UnaryOp {
268 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
269 let s = String::deserialize(d)?;
270 match s.as_str() {
271 "neg" => Ok(UnaryOp::Neg),
272 "not" => Ok(UnaryOp::Not),
273 other => Err(serde::de::Error::unknown_variant(other, &["neg", "not"])),
274 }
275 }
276}
277
278impl Serialize for ListPredKind {
281 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
282 let tag = match self {
283 ListPredKind::Any => "any",
284 ListPredKind::All => "all",
285 ListPredKind::None => "none",
286 ListPredKind::Single => "single",
287 };
288 s.serialize_str(tag)
289 }
290}
291
292impl<'de> Deserialize<'de> for ListPredKind {
293 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
294 let s = String::deserialize(d)?;
295 match s.as_str() {
296 "any" => Ok(ListPredKind::Any),
297 "all" => Ok(ListPredKind::All),
298 "none" => Ok(ListPredKind::None),
299 "single" => Ok(ListPredKind::Single),
300 other => Err(serde::de::Error::unknown_variant(
301 other,
302 &["any", "all", "none", "single"],
303 )),
304 }
305 }
306}
307
308#[derive(Serialize, Deserialize)]
311#[serde(deny_unknown_fields)]
312struct NodeSpecSer {
313 labels: LabelSet,
314 #[serde(skip_serializing_if = "Option::is_none")]
315 properties: Option<Expr>,
316}
317
318impl Serialize for NodeSpec {
319 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
320 NodeSpecSer {
321 labels: self.labels.clone(),
322 properties: self.properties.clone(),
323 }
324 .serialize(s)
325 }
326}
327
328impl<'de> Deserialize<'de> for NodeSpec {
329 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
330 let proxy = NodeSpecSer::deserialize(d)?;
331 Ok(NodeSpec {
332 labels: proxy.labels,
333 properties: proxy.properties,
334 })
335 }
336}
337
338#[derive(Serialize, Deserialize)]
339#[serde(deny_unknown_fields)]
340struct RelSpecSer {
341 types: Vec<SmolStr>,
342 direction: Direction,
343 length: RelLength,
344 #[serde(skip_serializing_if = "Option::is_none")]
345 properties: Option<Expr>,
346}
347
348impl Serialize for RelSpec {
349 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
350 RelSpecSer {
351 types: self.types.clone(),
352 direction: self.direction,
353 length: self.length.clone(),
354 properties: self.properties.clone(),
355 }
356 .serialize(s)
357 }
358}
359
360impl<'de> Deserialize<'de> for RelSpec {
361 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
362 let proxy = RelSpecSer::deserialize(d)?;
363 Ok(RelSpec {
364 types: proxy.types,
365 direction: proxy.direction,
366 length: proxy.length,
367 properties: proxy.properties,
368 })
369 }
370}
371
372#[derive(Serialize, Deserialize)]
375#[serde(deny_unknown_fields)]
376struct ProjectionSer {
377 expr: Expr,
378 alias: SmolStr,
379}
380
381impl Serialize for Projection {
382 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
383 ProjectionSer {
384 expr: self.expr.clone(),
385 alias: self.alias.clone(),
386 }
387 .serialize(s)
388 }
389}
390
391impl<'de> Deserialize<'de> for Projection {
392 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
393 let proxy = ProjectionSer::deserialize(d)?;
394 Ok(Projection {
395 expr: proxy.expr,
396 alias: proxy.alias,
397 })
398 }
399}
400
401#[derive(Serialize, Deserialize)]
402#[serde(deny_unknown_fields)]
403struct OrderKeySer {
404 expr: Expr,
405 dir: SortDir,
406}
407
408impl Serialize for OrderKey {
409 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
410 OrderKeySer {
411 expr: self.expr.clone(),
412 dir: self.dir,
413 }
414 .serialize(s)
415 }
416}
417
418impl<'de> Deserialize<'de> for OrderKey {
419 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
420 let proxy = OrderKeySer::deserialize(d)?;
421 Ok(OrderKey {
422 expr: proxy.expr,
423 dir: proxy.dir,
424 })
425 }
426}
427
428#[derive(Serialize, Deserialize)]
429#[serde(deny_unknown_fields)]
430struct AggExprSer {
431 func: SmolStr,
432 args: Vec<Expr>,
433 distinct: bool,
434}
435
436impl Serialize for AggExpr {
437 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
438 AggExprSer {
439 func: self.func.clone(),
440 args: self.args.clone(),
441 distinct: self.distinct,
442 }
443 .serialize(s)
444 }
445}
446
447impl<'de> Deserialize<'de> for AggExpr {
448 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
449 let proxy = AggExprSer::deserialize(d)?;
450 Ok(AggExpr {
451 func: proxy.func,
452 args: proxy.args,
453 distinct: proxy.distinct,
454 })
455 }
456}
457
458#[derive(Serialize, Deserialize)]
465#[serde(tag = "kind", rename_all = "snake_case")]
466enum ExprSer {
467 Null,
468 Bool {
469 value: bool,
470 },
471 Int {
472 value: i64,
473 },
474 Float {
475 value: f64,
476 },
477 #[serde(rename = "str")]
478 String {
479 value: SmolStr,
480 },
481 Var {
482 id: VarId,
483 },
484 Prop {
485 target: Box<Expr>,
486 prop: SmolStr,
487 },
488 Index {
489 target: Box<Expr>,
490 index: Box<Expr>,
491 },
492 Slice {
493 target: Box<Expr>,
494 #[serde(skip_serializing_if = "Option::is_none")]
495 start: Option<Box<Expr>>,
496 #[serde(skip_serializing_if = "Option::is_none")]
497 end: Option<Box<Expr>>,
498 },
499 List {
500 items: Vec<Expr>,
501 },
502 Map {
503 entries: Vec<(SmolStr, Expr)>,
505 },
506 Call {
507 func: SmolStr,
508 args: Vec<Expr>,
509 },
510 BinOp {
511 bin_op: BinOp,
512 lhs: Box<Expr>,
513 rhs: Box<Expr>,
514 },
515 UnaryOp {
516 unary_op: UnaryOp,
517 operand: Box<Expr>,
518 },
519 Case {
520 #[serde(skip_serializing_if = "Option::is_none")]
521 scrutinee: Option<Box<Expr>>,
522 arms: Vec<(Expr, Expr)>,
523 #[serde(skip_serializing_if = "Option::is_none")]
524 otherwise: Option<Box<Expr>>,
525 },
526 IsNull {
527 operand: Box<Expr>,
528 negated: bool,
529 },
530 InList {
531 operand: Box<Expr>,
532 list: Box<Expr>,
533 },
534 ListPredicate {
535 #[serde(rename = "pred_kind")]
536 kind: ListPredKind,
537 var: VarId,
538 iterable: Box<Expr>,
539 #[serde(skip_serializing_if = "Option::is_none")]
540 predicate: Option<Box<Expr>>,
541 },
542 Param {
543 name: SmolStr,
544 },
545 Exists {
548 pattern: Box<ReadOp>,
549 },
550}
551
552impl Serialize for Expr {
553 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
554 let proxy: ExprSer = match self {
555 Expr::Null => ExprSer::Null,
556 Expr::Bool(v) => ExprSer::Bool { value: *v },
557 Expr::Int(v) => ExprSer::Int { value: *v },
558 Expr::Float(v) => ExprSer::Float { value: *v },
559 Expr::String(v) => ExprSer::String { value: v.clone() },
560 Expr::Var(id) => ExprSer::Var { id: *id },
561 Expr::Prop { target, prop } => ExprSer::Prop {
562 target: Box::new(*target.clone()),
563 prop: prop.clone(),
564 },
565 Expr::Index { target, index } => ExprSer::Index {
566 target: Box::new(*target.clone()),
567 index: Box::new(*index.clone()),
568 },
569 Expr::Slice { target, start, end } => ExprSer::Slice {
570 target: Box::new(*target.clone()),
571 start: start.as_ref().map(|e| Box::new(*e.clone())),
572 end: end.as_ref().map(|e| Box::new(*e.clone())),
573 },
574 Expr::List(items) => ExprSer::List {
575 items: items.clone(),
576 },
577 Expr::Map(entries) => ExprSer::Map {
578 entries: entries.clone(),
579 },
580 Expr::Call { func, args } => ExprSer::Call {
581 func: func.clone(),
582 args: args.clone(),
583 },
584 Expr::BinOp { op, lhs, rhs } => ExprSer::BinOp {
585 bin_op: *op,
586 lhs: Box::new(*lhs.clone()),
587 rhs: Box::new(*rhs.clone()),
588 },
589 Expr::UnaryOp { op, operand } => ExprSer::UnaryOp {
590 unary_op: *op,
591 operand: Box::new(*operand.clone()),
592 },
593 Expr::Case {
594 scrutinee,
595 arms,
596 otherwise,
597 } => ExprSer::Case {
598 scrutinee: scrutinee.as_ref().map(|e| Box::new(*e.clone())),
599 arms: arms.clone(),
600 otherwise: otherwise.as_ref().map(|e| Box::new(*e.clone())),
601 },
602 Expr::IsNull { operand, negated } => ExprSer::IsNull {
603 operand: Box::new(*operand.clone()),
604 negated: *negated,
605 },
606 Expr::InList { operand, list } => ExprSer::InList {
607 operand: Box::new(*operand.clone()),
608 list: Box::new(*list.clone()),
609 },
610 Expr::ListPredicate {
611 kind,
612 var,
613 iterable,
614 predicate,
615 } => ExprSer::ListPredicate {
616 kind: *kind,
617 var: *var,
618 iterable: Box::new(*iterable.clone()),
619 predicate: predicate.as_ref().map(|p| Box::new(*p.clone())),
620 },
621 Expr::Param { name } => ExprSer::Param { name: name.clone() },
622 Expr::Exists { pattern } => ExprSer::Exists {
623 pattern: pattern.clone(),
624 },
625 };
626 proxy.serialize(s)
627 }
628}
629
630impl<'de> Deserialize<'de> for Expr {
631 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
632 let proxy = ExprSer::deserialize(d)?;
633 Ok(match proxy {
634 ExprSer::Null => Expr::Null,
635 ExprSer::Bool { value } => Expr::Bool(value),
636 ExprSer::Int { value } => Expr::Int(value),
637 ExprSer::Float { value } => Expr::Float(value),
638 ExprSer::String { value } => Expr::String(value),
639 ExprSer::Var { id } => Expr::Var(id),
640 ExprSer::Prop { target, prop } => Expr::Prop {
641 target: Box::new(*target),
642 prop,
643 },
644 ExprSer::Index { target, index } => Expr::Index {
645 target: Box::new(*target),
646 index: Box::new(*index),
647 },
648 ExprSer::Slice { target, start, end } => Expr::Slice {
649 target: Box::new(*target),
650 start: start.map(|e| Box::new(*e)),
651 end: end.map(|e| Box::new(*e)),
652 },
653 ExprSer::List { items } => Expr::List(items),
654 ExprSer::Map { entries } => Expr::Map(entries),
655 ExprSer::Call { func, args } => Expr::Call { func, args },
656 ExprSer::BinOp { bin_op, lhs, rhs } => Expr::BinOp {
657 op: bin_op,
658 lhs: Box::new(*lhs),
659 rhs: Box::new(*rhs),
660 },
661 ExprSer::UnaryOp { unary_op, operand } => Expr::UnaryOp {
662 op: unary_op,
663 operand: Box::new(*operand),
664 },
665 ExprSer::Case {
666 scrutinee,
667 arms,
668 otherwise,
669 } => Expr::Case {
670 scrutinee: scrutinee.map(|e| Box::new(*e)),
671 arms,
672 otherwise: otherwise.map(|e| Box::new(*e)),
673 },
674 ExprSer::IsNull { operand, negated } => Expr::IsNull {
675 operand: Box::new(*operand),
676 negated,
677 },
678 ExprSer::InList { operand, list } => Expr::InList {
679 operand: Box::new(*operand),
680 list: Box::new(*list),
681 },
682 ExprSer::ListPredicate {
683 kind,
684 var,
685 iterable,
686 predicate,
687 } => Expr::ListPredicate {
688 kind,
689 var,
690 iterable: Box::new(*iterable),
691 predicate: predicate.map(|p| Box::new(*p)),
692 },
693 ExprSer::Param { name } => Expr::Param { name },
694 ExprSer::Exists { pattern } => Expr::Exists { pattern },
695 })
696 }
697}
698
699#[derive(Serialize, Deserialize)]
702#[serde(tag = "op", rename_all = "snake_case")]
703enum ReadOpSer {
704 Source {
705 #[serde(skip_serializing_if = "Option::is_none")]
706 label: Option<LabelSet>,
707 bind: VarId,
708 },
709 Expand {
710 input: OpId,
711 from: VarId,
712 rel: RelSpec,
713 to: NodeSpec,
714 bind_rel: VarId,
715 bind_to: VarId,
716 },
717 Filter {
718 input: OpId,
719 predicate: Expr,
720 },
721 Project {
722 input: OpId,
723 items: Vec<Projection>,
724 },
725 Aggregate {
726 input: OpId,
727 keys: Vec<Expr>,
728 aggs: Vec<AggExpr>,
729 },
730 OrderBy {
731 input: OpId,
732 keys: Vec<OrderKey>,
733 },
734 Skip {
735 input: OpId,
736 count: Expr,
737 },
738 Limit {
739 input: OpId,
740 count: Expr,
741 },
742 Distinct {
743 input: OpId,
744 },
745 Unwind {
746 input: OpId,
747 list: Expr,
748 bind: VarId,
749 },
750 Union {
751 left: OpId,
752 right: OpId,
753 kind: UnionKind,
754 },
755 With {
756 input: OpId,
757 items: Vec<Projection>,
758 #[serde(skip_serializing_if = "Option::is_none")]
759 filter: Option<Expr>,
760 },
761 OptionalJoin {
762 input: OpId,
763 pattern: Box<ReadOp>,
764 },
765}
766
767impl Serialize for ReadOp {
768 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
769 let proxy: ReadOpSer = match self {
770 ReadOp::Source { label, bind } => ReadOpSer::Source {
771 label: label.clone(),
772 bind: *bind,
773 },
774 ReadOp::Expand {
775 input,
776 from,
777 rel,
778 to,
779 bind_rel,
780 bind_to,
781 } => ReadOpSer::Expand {
782 input: *input,
783 from: *from,
784 rel: rel.clone(),
785 to: to.clone(),
786 bind_rel: *bind_rel,
787 bind_to: *bind_to,
788 },
789 ReadOp::Filter { input, predicate } => ReadOpSer::Filter {
790 input: *input,
791 predicate: predicate.clone(),
792 },
793 ReadOp::Project { input, items } => ReadOpSer::Project {
794 input: *input,
795 items: items.clone(),
796 },
797 ReadOp::Aggregate { input, keys, aggs } => ReadOpSer::Aggregate {
798 input: *input,
799 keys: keys.clone(),
800 aggs: aggs.clone(),
801 },
802 ReadOp::OrderBy { input, keys } => ReadOpSer::OrderBy {
803 input: *input,
804 keys: keys.clone(),
805 },
806 ReadOp::Skip { input, count } => ReadOpSer::Skip {
807 input: *input,
808 count: count.clone(),
809 },
810 ReadOp::Limit { input, count } => ReadOpSer::Limit {
811 input: *input,
812 count: count.clone(),
813 },
814 ReadOp::Distinct { input } => ReadOpSer::Distinct { input: *input },
815 ReadOp::Unwind { input, list, bind } => ReadOpSer::Unwind {
816 input: *input,
817 list: list.clone(),
818 bind: *bind,
819 },
820 ReadOp::Union { left, right, kind } => ReadOpSer::Union {
821 left: *left,
822 right: *right,
823 kind: *kind,
824 },
825 ReadOp::With {
826 input,
827 items,
828 filter,
829 } => ReadOpSer::With {
830 input: *input,
831 items: items.clone(),
832 filter: filter.clone(),
833 },
834 ReadOp::OptionalJoin { input, pattern } => ReadOpSer::OptionalJoin {
835 input: *input,
836 pattern: pattern.clone(),
837 },
838 };
839 proxy.serialize(s)
840 }
841}
842
843impl<'de> Deserialize<'de> for ReadOp {
844 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
845 let proxy = ReadOpSer::deserialize(d)?;
846 Ok(match proxy {
847 ReadOpSer::Source { label, bind } => ReadOp::Source { label, bind },
848 ReadOpSer::Expand {
849 input,
850 from,
851 rel,
852 to,
853 bind_rel,
854 bind_to,
855 } => ReadOp::Expand {
856 input,
857 from,
858 rel,
859 to,
860 bind_rel,
861 bind_to,
862 },
863 ReadOpSer::Filter { input, predicate } => ReadOp::Filter { input, predicate },
864 ReadOpSer::Project { input, items } => ReadOp::Project { input, items },
865 ReadOpSer::Aggregate { input, keys, aggs } => ReadOp::Aggregate { input, keys, aggs },
866 ReadOpSer::OrderBy { input, keys } => ReadOp::OrderBy { input, keys },
867 ReadOpSer::Skip { input, count } => ReadOp::Skip { input, count },
868 ReadOpSer::Limit { input, count } => ReadOp::Limit { input, count },
869 ReadOpSer::Distinct { input } => ReadOp::Distinct { input },
870 ReadOpSer::Unwind { input, list, bind } => ReadOp::Unwind { input, list, bind },
871 ReadOpSer::Union { left, right, kind } => ReadOp::Union { left, right, kind },
872 ReadOpSer::With {
873 input,
874 items,
875 filter,
876 } => ReadOp::With {
877 input,
878 items,
879 filter,
880 },
881 ReadOpSer::OptionalJoin { input, pattern } => ReadOp::OptionalJoin { input, pattern },
882 })
883 }
884}
885
886#[derive(Serialize, Deserialize)]
889#[serde(tag = "op", rename_all = "snake_case")]
890enum WriteOpSer {
891 CreateNode {
892 labels: Vec<SmolStr>,
893 props: Expr,
894 #[serde(skip_serializing_if = "Option::is_none")]
895 bind: Option<VarId>,
896 },
897 CreateRel {
898 from: VarId,
899 to: VarId,
900 rel_type: SmolStr,
901 props: Expr,
902 #[serde(skip_serializing_if = "Option::is_none")]
903 bind: Option<VarId>,
904 },
905 MergeNode {
906 labels: Vec<SmolStr>,
907 props: Expr,
908 on_create: Vec<WriteOp>,
909 on_match: Vec<WriteOp>,
910 #[serde(skip_serializing_if = "Option::is_none")]
911 bind: Option<VarId>,
912 },
913 MergeRel {
914 from: VarId,
915 to: VarId,
916 rel_type: SmolStr,
917 props: Expr,
918 on_create: Vec<WriteOp>,
919 on_match: Vec<WriteOp>,
920 #[serde(skip_serializing_if = "Option::is_none")]
921 bind: Option<VarId>,
922 },
923 SetProperty {
924 target: VarId,
925 prop: SmolStr,
926 value: Expr,
927 },
928 SetLabels {
929 target: VarId,
930 labels: Vec<SmolStr>,
931 },
932 RemoveProperty {
933 target: VarId,
934 prop: SmolStr,
935 },
936 RemoveLabels {
937 target: VarId,
938 labels: Vec<SmolStr>,
939 },
940 Delete {
941 targets: Vec<Expr>,
942 detach: bool,
943 },
944}
945
946impl Serialize for WriteOp {
947 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
948 let proxy: WriteOpSer = match self {
949 WriteOp::CreateNode {
950 labels,
951 props,
952 bind,
953 } => WriteOpSer::CreateNode {
954 labels: labels.clone(),
955 props: props.clone(),
956 bind: *bind,
957 },
958 WriteOp::CreateRel {
959 from,
960 to,
961 rel_type,
962 props,
963 bind,
964 } => WriteOpSer::CreateRel {
965 from: *from,
966 to: *to,
967 rel_type: rel_type.clone(),
968 props: props.clone(),
969 bind: *bind,
970 },
971 WriteOp::MergeNode {
972 labels,
973 props,
974 on_create,
975 on_match,
976 bind,
977 } => WriteOpSer::MergeNode {
978 labels: labels.clone(),
979 props: props.clone(),
980 on_create: on_create.clone(),
981 on_match: on_match.clone(),
982 bind: *bind,
983 },
984 WriteOp::MergeRel {
985 from,
986 to,
987 rel_type,
988 props,
989 on_create,
990 on_match,
991 bind,
992 } => WriteOpSer::MergeRel {
993 from: *from,
994 to: *to,
995 rel_type: rel_type.clone(),
996 props: props.clone(),
997 on_create: on_create.clone(),
998 on_match: on_match.clone(),
999 bind: *bind,
1000 },
1001 WriteOp::SetProperty {
1002 target,
1003 prop,
1004 value,
1005 } => WriteOpSer::SetProperty {
1006 target: *target,
1007 prop: prop.clone(),
1008 value: value.clone(),
1009 },
1010 WriteOp::SetLabels { target, labels } => WriteOpSer::SetLabels {
1011 target: *target,
1012 labels: labels.clone(),
1013 },
1014 WriteOp::RemoveProperty { target, prop } => WriteOpSer::RemoveProperty {
1015 target: *target,
1016 prop: prop.clone(),
1017 },
1018 WriteOp::RemoveLabels { target, labels } => WriteOpSer::RemoveLabels {
1019 target: *target,
1020 labels: labels.clone(),
1021 },
1022 WriteOp::Delete { targets, detach } => WriteOpSer::Delete {
1023 targets: targets.clone(),
1024 detach: *detach,
1025 },
1026 };
1027 proxy.serialize(s)
1028 }
1029}
1030
1031impl<'de> Deserialize<'de> for WriteOp {
1032 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
1033 let proxy = WriteOpSer::deserialize(d)?;
1034 Ok(match proxy {
1035 WriteOpSer::CreateNode {
1036 labels,
1037 props,
1038 bind,
1039 } => WriteOp::CreateNode {
1040 labels,
1041 props,
1042 bind,
1043 },
1044 WriteOpSer::CreateRel {
1045 from,
1046 to,
1047 rel_type,
1048 props,
1049 bind,
1050 } => WriteOp::CreateRel {
1051 from,
1052 to,
1053 rel_type,
1054 props,
1055 bind,
1056 },
1057 WriteOpSer::MergeNode {
1058 labels,
1059 props,
1060 on_create,
1061 on_match,
1062 bind,
1063 } => WriteOp::MergeNode {
1064 labels,
1065 props,
1066 on_create,
1067 on_match,
1068 bind,
1069 },
1070 WriteOpSer::MergeRel {
1071 from,
1072 to,
1073 rel_type,
1074 props,
1075 on_create,
1076 on_match,
1077 bind,
1078 } => WriteOp::MergeRel {
1079 from,
1080 to,
1081 rel_type,
1082 props,
1083 on_create,
1084 on_match,
1085 bind,
1086 },
1087 WriteOpSer::SetProperty {
1088 target,
1089 prop,
1090 value,
1091 } => WriteOp::SetProperty {
1092 target,
1093 prop,
1094 value,
1095 },
1096 WriteOpSer::SetLabels { target, labels } => WriteOp::SetLabels { target, labels },
1097 WriteOpSer::RemoveProperty { target, prop } => WriteOp::RemoveProperty { target, prop },
1098 WriteOpSer::RemoveLabels { target, labels } => WriteOp::RemoveLabels { target, labels },
1099 WriteOpSer::Delete { targets, detach } => WriteOp::Delete { targets, detach },
1100 })
1101 }
1102}
1103
1104use crate::lower::PlanStatement;
1110use cyrs_hir::VarId as HirVarId;
1111use indexmap::IndexMap;
1112
1113#[derive(Serialize, Deserialize)]
1114#[serde(deny_unknown_fields)]
1115struct PlanStatementSer {
1116 ops: Vec<ReadOp>,
1117 write_ops: Vec<WriteOp>,
1118 var_map: Vec<(u32, u32)>,
1121}
1122
1123impl Serialize for PlanStatement {
1124 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
1125 let var_map: Vec<(u32, u32)> = self
1126 .var_map
1127 .iter()
1128 .map(|(plan_v, hir_v)| (plan_v.0, hir_v.0))
1129 .collect();
1130 PlanStatementSer {
1131 ops: self.ops.clone(),
1132 write_ops: self.write_ops.clone(),
1133 var_map,
1134 }
1135 .serialize(s)
1136 }
1137}
1138
1139impl<'de> Deserialize<'de> for PlanStatement {
1140 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
1141 let proxy = PlanStatementSer::deserialize(d)?;
1142 let mut var_map: IndexMap<VarId, HirVarId> = IndexMap::with_capacity(proxy.var_map.len());
1143 for (plan_v, hir_v) in proxy.var_map {
1144 var_map.insert(VarId(plan_v), HirVarId(hir_v));
1145 }
1146 Ok(PlanStatement {
1147 ops: proxy.ops,
1148 write_ops: proxy.write_ops,
1149 var_map,
1150 })
1151 }
1152}