1use crate::conversion::FromGValue;
2use crate::process::traversal::step::by::ByStep;
3use crate::process::traversal::step::choose::IntoChooseStep;
4use crate::process::traversal::step::coalesce::CoalesceStep;
5use crate::process::traversal::step::dedup::DedupStep;
6use crate::process::traversal::step::from::FromStep;
7use crate::process::traversal::step::has::HasStep;
8use crate::process::traversal::step::limit::LimitStep;
9use crate::process::traversal::step::local::LocalStep;
10use crate::process::traversal::step::loops::LoopsStep;
11use crate::process::traversal::step::match_step::MatchStep;
12use crate::process::traversal::step::not::NotStep;
13use crate::process::traversal::step::or::OrStep;
14use crate::process::traversal::step::repeat::RepeatStep;
15use crate::process::traversal::step::select::SelectStep;
16use crate::process::traversal::step::to::ToStep;
17use crate::process::traversal::step::until::UntilStep;
18use crate::process::traversal::step::where_step::WhereStep;
19
20use crate::process::traversal::internal::Terminator;
21use crate::process::traversal::{Bytecode, Scope, TraversalBuilder, WRITE_OPERATORS};
22use crate::structure::{Cardinality, Labels};
23use crate::{
24 structure::GIDs, structure::GProperty, structure::IntoPredicate, Edge, GValue, List, Map, Path,
25 Vertex,
26};
27use std::marker::PhantomData;
28
29#[derive(Clone)]
30pub struct GraphTraversal<S, E: FromGValue, T: Terminator<E>> {
31 start: PhantomData<S>,
32 end: PhantomData<E>,
33 pub(crate) builder: TraversalBuilder,
34 terminator: T,
35}
36
37impl<S, E: FromGValue, T: Terminator<E>> GraphTraversal<S, E, T> {
38 pub fn new(terminator: T, builder: TraversalBuilder) -> GraphTraversal<S, E, T> {
39 GraphTraversal {
40 start: PhantomData,
41 end: PhantomData,
42 builder,
43 terminator,
44 }
45 }
46
47 pub fn does_write(&self) -> bool {
48 self.bytecode()
49 .steps()
50 .iter()
51 .any(|instruction| WRITE_OPERATORS.contains(&instruction.operator().as_ref()))
52 }
53
54 pub fn bytecode(&self) -> &Bytecode {
55 &self.builder.bytecode
56 }
57
58 pub fn has_label<L>(mut self, labels: L) -> Self
59 where
60 L: Into<Labels>,
61 {
62 self.builder = self.builder.has_label(labels);
63 self
64 }
65
66 pub fn add_v<A>(mut self, label: A) -> GraphTraversal<Vertex, Vertex, T>
67 where
68 A: Into<Labels>,
69 T: Terminator<Vertex>,
70 {
71 self.builder = self.builder.add_v(label);
72
73 GraphTraversal::new(self.terminator, self.builder)
74 }
75
76 pub fn property<A>(mut self, key: &str, value: A) -> Self
77 where
78 A: Into<GValue>,
79 {
80 self.builder = self.builder.property(key, value);
81 self
82 }
83
84 pub fn property_with_cardinality<A>(
85 mut self,
86 cardinality: Cardinality,
87 key: &str,
88 value: A,
89 ) -> Self
90 where
91 A: Into<GValue>,
92 {
93 self.builder = self.builder.property_with_cardinality(cardinality, key, value);
94 self
95 }
96
97 pub fn property_many<A>(mut self, values: Vec<(&str, A)>) -> Self
98 where
99 A: Into<GValue>,
100 {
101 for property in values {
102 self.builder = self.builder.property::<&str, A>(property.0.as_ref(), property.1)
103 }
104
105 self
106 }
107
108 pub fn property_many_with_cardinality<A>(
109 mut self,
110 values: Vec<(Cardinality, String, A)>,
111 ) -> Self
112 where
113 A: Into<GValue>,
114 {
115 for property in values {
116 self.builder =
117 self.builder.property_with_cardinality(property.0, property.1.as_ref(), property.2);
118 }
119
120 self
121 }
122
123 pub fn has<A>(mut self, step: A) -> Self
124 where
125 A: Into<HasStep>,
126 {
127 self.builder = self.builder.has(step);
128
129 self
130 }
131
132 pub fn has_many<A>(mut self, steps: Vec<A>) -> Self
133 where
134 A: Into<HasStep>,
135 {
136 self.builder = self.builder.has_many(steps);
137
138 self
139 }
140
141 pub fn has_not<A>(mut self, key: A) -> Self
142 where
143 A: Into<String>,
144 {
145 self.builder = self.builder.has_not(key);
146 self
147 }
148
149 pub fn has_key<A>(mut self, key: A) -> Self
150 where
151 A: Into<String>,
152 {
153 self.builder = self.builder.has_key(key);
154 self
155 }
156
157 pub fn as_<A>(mut self, alias: A) -> Self
158 where
159 A: Into<String>,
160 {
161 self.builder = self.builder.as_(alias);
162
163 self
164 }
165
166 pub fn with_side_effect<A>(mut self, step: (&'static str, A)) -> Self
167 where
168 A: Into<GValue> + FromGValue,
169 {
170 self.builder = self.builder.with_side_effect(step);
171
172 self
173 }
174
175 pub fn add_e<A>(mut self, label: A) -> GraphTraversal<S, Edge, T>
176 where
177 A: Into<String>,
178 T: Terminator<Edge>,
179 {
180 self.builder = self.builder.add_e(label);
181
182 GraphTraversal::new(self.terminator, self.builder)
183 }
184
185 pub fn out<A>(mut self, labels: A) -> GraphTraversal<S, Vertex, T>
186 where
187 A: Into<Labels>,
188 T: Terminator<Vertex>,
189 {
190 self.builder = self.builder.out(labels);
191
192 GraphTraversal::new(self.terminator, self.builder)
193 }
194
195 pub fn out_e<A>(mut self, labels: A) -> GraphTraversal<S, Edge, T>
196 where
197 A: Into<Labels>,
198 T: Terminator<Edge>,
199 {
200 self.builder = self.builder.out_e(labels);
201
202 GraphTraversal::new(self.terminator, self.builder)
203 }
204
205 pub fn out_v(mut self) -> GraphTraversal<S, Vertex, T>
206 where
207 T: Terminator<Vertex>,
208 {
209 self.builder = self.builder.out_v();
210
211 GraphTraversal::new(self.terminator, self.builder)
212 }
213 pub fn in_<A>(mut self, labels: A) -> GraphTraversal<S, Vertex, T>
214 where
215 A: Into<Labels>,
216 T: Terminator<Vertex>,
217 {
218 self.builder = self.builder.in_(labels);
219
220 GraphTraversal::new(self.terminator, self.builder)
221 }
222
223 pub fn in_e<A>(mut self, labels: A) -> GraphTraversal<S, Edge, T>
224 where
225 A: Into<Labels>,
226 T: Terminator<Edge>,
227 {
228 self.builder = self.builder.in_e(labels);
229
230 GraphTraversal::new(self.terminator, self.builder)
231 }
232
233 pub fn in_v(mut self) -> GraphTraversal<S, Vertex, T>
234 where
235 T: Terminator<Vertex>,
236 {
237 self.builder = self.builder.in_v();
238
239 GraphTraversal::new(self.terminator, self.builder)
240 }
241
242 pub fn both<A>(mut self, labels: A) -> GraphTraversal<S, Vertex, T>
243 where
244 A: Into<Labels>,
245 T: Terminator<Vertex>,
246 {
247 self.builder = self.builder.both(labels);
248
249 GraphTraversal::new(self.terminator, self.builder)
250 }
251
252 pub fn both_e<A>(mut self, labels: A) -> GraphTraversal<S, Edge, T>
253 where
254 A: Into<Labels>,
255 T: Terminator<Edge>,
256 {
257 self.builder = self.builder.both_e(labels);
258
259 GraphTraversal::new(self.terminator, self.builder)
260 }
261
262 pub fn other(mut self) -> GraphTraversal<S, Vertex, T>
263 where
264 T: Terminator<Vertex>,
265 {
266 self.builder = self.builder.other();
267
268 GraphTraversal::new(self.terminator, self.builder)
269 }
270
271 pub fn other_v(mut self) -> GraphTraversal<S, Vertex, T>
272 where
273 T: Terminator<Vertex>,
274 {
275 self.builder = self.builder.other_v();
276
277 GraphTraversal::new(self.terminator, self.builder)
278 }
279
280 pub fn label(mut self) -> GraphTraversal<S, String, T>
281 where
282 T: Terminator<String>,
283 {
284 self.builder = self.builder.label();
285
286 GraphTraversal::new(self.terminator, self.builder)
287 }
288
289 pub fn exec(&self) -> T::Executor {
290 self.terminator.exec(self)
291 }
292
293 pub fn from<A>(mut self, target: A) -> Self
294 where
295 A: Into<FromStep>,
296 {
297 self.builder = self.builder.from(target);
298
299 self
300 }
301
302 pub fn to<A>(mut self, target: A) -> Self
303 where
304 A: Into<ToStep>,
305 {
306 self.builder = self.builder.to(target);
307
308 self
309 }
310
311 pub fn properties<L>(mut self, labels: L) -> GraphTraversal<S, GProperty, T>
312 where
313 L: Into<Labels>,
314 T: Terminator<GProperty>,
315 {
316 self.builder = self.builder.properties(labels);
317 GraphTraversal::new(self.terminator, self.builder)
318 }
319
320 pub fn property_map<L>(mut self, labels: L) -> GraphTraversal<S, Map, T>
321 where
322 L: Into<Labels>,
323 T: Terminator<Map>,
324 {
325 self.builder = self.builder.property_map(labels);
326 GraphTraversal::new(self.terminator, self.builder)
327 }
328
329 pub fn values<L>(mut self, labels: L) -> GraphTraversal<S, GValue, T>
330 where
331 L: Into<Labels>,
332 T: Terminator<GValue>,
333 {
334 self.builder = self.builder.values(labels);
335 GraphTraversal::new(self.terminator, self.builder)
336 }
337
338 pub fn value_map<L>(mut self, labels: L) -> GraphTraversal<S, Map, T>
339 where
340 L: Into<Labels>,
341 T: Terminator<Map>,
342 {
343 self.builder = self.builder.value_map(labels);
344 GraphTraversal::new(self.terminator, self.builder)
345 }
346
347 pub fn element_map<L>(mut self, labels: L) -> GraphTraversal<S, Map, T>
348 where
349 L: Into<Labels>,
350 T: Terminator<Map>,
351 {
352 self.builder = self.builder.element_map(labels);
353 GraphTraversal::new(self.terminator, self.builder)
354 }
355
356 pub fn count(mut self) -> GraphTraversal<S, i64, T>
357 where
358 T: Terminator<i64>,
359 {
360 self.builder = self.builder.count();
361 GraphTraversal::new(self.terminator, self.builder)
362 }
363
364 pub fn group_count(mut self) -> GraphTraversal<S, Map, T>
365 where
366 T: Terminator<Map>,
367 {
368 self.builder = self.builder.group_count(None);
369 GraphTraversal::new(self.terminator, self.builder)
370 }
371
372 pub fn group_count_as<A>(mut self, key: A) -> GraphTraversal<S, E, T>
373 where
374 T: Terminator<Map>,
375 A: Into<String>,
376 {
377 self.builder = self.builder.group_count(Some(key.into()));
378 self
379 }
380
381 pub fn group(mut self) -> GraphTraversal<S, Map, T>
382 where
383 T: Terminator<Map>,
384 {
385 self.builder = self.builder.group(None);
386 GraphTraversal::new(self.terminator, self.builder)
387 }
388
389 pub fn group_as<A>(mut self, key: A) -> GraphTraversal<S, E, T>
390 where
391 T: Terminator<Map>,
392 A: Into<String>,
393 {
394 self.builder = self.builder.group(Some(key.into()));
395 self
396 }
397
398 pub fn by<A>(mut self, step: A) -> Self
399 where
400 A: Into<ByStep>,
401 {
402 self.builder = self.builder.by(step);
403 self
404 }
405
406 pub fn select<A>(mut self, step: A) -> GraphTraversal<S, GValue, T>
407 where
408 A: Into<SelectStep>,
409 T: Terminator<GValue>,
410 {
411 self.builder = self.builder.select(step);
412 GraphTraversal::new(self.terminator, self.builder)
413 }
414
415 pub fn fold(mut self) -> GraphTraversal<S, List, T>
416 where
417 T: Terminator<List>,
418 {
419 self.builder = self.builder.fold();
420 GraphTraversal::new(self.terminator, self.builder)
421 }
422 pub fn unfold(mut self) -> Self {
423 self.builder = self.builder.unfold();
424 self
425 }
426
427 pub fn path(mut self) -> GraphTraversal<S, Path, T>
428 where
429 T: Terminator<Path>,
430 {
431 self.builder = self.builder.path();
432 GraphTraversal::new(self.terminator, self.builder)
433 }
434
435 pub fn limit<A>(mut self, limit: A) -> Self
436 where
437 A: Into<LimitStep>,
438 {
439 self.builder = self.builder.limit(limit);
440
441 self
442 }
443
444 pub fn dedup<A>(mut self, dedup: A) -> Self
445 where
446 A: Into<DedupStep>,
447 {
448 self.builder = self.builder.dedup(dedup);
449 self
450 }
451
452 pub fn sum<A>(mut self, scope: A) -> GraphTraversal<S, GValue, T>
453 where
454 A: Into<Scope>,
455 T: Terminator<GValue>,
456 {
457 self.builder = self.builder.sum(scope);
458
459 GraphTraversal::new(self.terminator, self.builder)
460 }
461
462 pub fn max<A>(mut self, scope: A) -> GraphTraversal<S, GValue, T>
463 where
464 A: Into<Scope>,
465 T: Terminator<GValue>,
466 {
467 self.builder = self.builder.max(scope);
468
469 GraphTraversal::new(self.terminator, self.builder)
470 }
471
472 pub fn mean<A>(mut self, scope: A) -> GraphTraversal<S, GValue, T>
473 where
474 A: Into<Scope>,
475 T: Terminator<GValue>,
476 {
477 self.builder = self.builder.mean(scope);
478
479 GraphTraversal::new(self.terminator, self.builder)
480 }
481
482 pub fn min<A>(mut self, scope: A) -> GraphTraversal<S, GValue, T>
483 where
484 A: Into<Scope>,
485 T: Terminator<GValue>,
486 {
487 self.builder = self.builder.min(scope);
488
489 GraphTraversal::new(self.terminator, self.builder)
490 }
491
492 pub fn is<A>(mut self, val: A) -> Self
493 where
494 A: IntoPredicate,
495 {
496 self.builder = self.builder.is(val);
497
498 self
499 }
500
501 pub fn where_<A>(mut self, step: A) -> Self
502 where
503 A: Into<WhereStep>,
504 {
505 self.builder = self.builder.where_(step);
506
507 self
508 }
509
510 pub fn not<A>(mut self, step: A) -> Self
511 where
512 A: Into<NotStep>,
513 {
514 self.builder = self.builder.not(step);
515 self
516 }
517
518 pub fn order<A>(mut self, scope: A) -> Self
519 where
520 A: Into<Scope>,
521 {
522 self.builder = self.builder.order(scope);
523
524 self
525 }
526
527 pub fn match_<A>(mut self, step: A) -> GraphTraversal<S, Map, T>
528 where
529 A: Into<MatchStep>,
530 T: Terminator<Map>,
531 {
532 self.builder = self.builder.match_(step);
533 GraphTraversal::new(self.terminator, self.builder)
534 }
535
536 pub fn drop(mut self) -> Self {
537 self.builder = self.builder.drop();
538 self
539 }
540
541 pub fn or<A>(mut self, step: A) -> Self
542 where
543 A: Into<OrStep>,
544 {
545 self.builder = self.builder.or(step);
546 self
547 }
548
549 pub fn map<A>(mut self, step: A) -> Self
550 where
551 A: Into<ByStep>,
552 {
553 self.builder = self.builder.map(step);
554 self
555 }
556
557 pub fn project<A>(mut self, step: A) -> GraphTraversal<S, GValue, T>
558 where
559 A: Into<SelectStep>,
560 T: Terminator<GValue>,
561 {
562 self.builder = self.builder.project(step);
563 GraphTraversal::new(self.terminator, self.builder)
564 }
565
566 pub fn v<VT>(mut self, ids: VT) -> Self
567 where
568 VT: Into<GIDs>,
569 {
570 self.builder = self.builder.v(ids);
571 self
572 }
573
574 pub fn repeat<A>(mut self, step: A) -> Self
575 where
576 A: Into<RepeatStep>,
577 {
578 self.builder = self.builder.repeat(step);
579 self
580 }
581
582 pub fn until<A>(mut self, step: A) -> Self
583 where
584 A: Into<UntilStep>,
585 {
586 self.builder = self.builder.until(step);
587 self
588 }
589
590 pub fn simple_path(mut self) -> Self {
591 self.builder = self.builder.simple_path();
592 self
593 }
594
595 pub fn sample(mut self, step: i32) -> Self {
596 self.builder = self.builder.sample(step);
597 self
598 }
599
600 pub fn loops<A>(mut self, step: A) -> Self
601 where
602 A: Into<LoopsStep>,
603 {
604 self.builder = self.builder.loops(step);
605 self
606 }
607
608 pub fn local<A>(mut self, step: A) -> Self
609 where
610 A: Into<LocalStep>,
611 {
612 self.builder = self.builder.local(step);
613 self
614 }
615
616 pub fn aggregate<A>(mut self, alias: A) -> Self
617 where
618 A: Into<String>,
619 {
620 self.builder = self.builder.aggregate(alias);
621 self
622 }
623
624 pub fn value(mut self) -> Self {
625 self.builder = self.builder.value();
626
627 self
628 }
629
630 pub fn choose<A>(mut self, step: A) -> Self
631 where
632 A: IntoChooseStep,
633 {
634 self.builder = self.builder.choose(step);
635 self
636 }
637
638 pub fn coalesce<B, A>(mut self, colaesce: A) -> GraphTraversal<S, B, T>
639 where
640 A: Into<CoalesceStep>,
641 B: FromGValue,
642 T: Terminator<B>,
643 {
644 self.builder = self.builder.coalesce(colaesce);
645
646 GraphTraversal::new(self.terminator, self.builder)
647 }
648
649 pub fn identity(mut self) -> Self {
650 self.builder = self.builder.identity();
651 self
652 }
653
654 pub fn range(mut self, step: i64, step2: i64) -> Self {
655 self.builder = self.builder.range(step, step2);
656 self
657 }
658
659 pub fn cap(mut self, step: &'static str) -> Self {
660 self.builder = self.builder.cap(step);
661 self
662 }
663
664 pub fn barrier(mut self) -> Self {
665 self.builder = self.builder.barrier();
666 self
667 }
668
669 pub fn optional(mut self, step: TraversalBuilder) -> Self {
670 self.builder = self.builder.optional(step);
671 self
672 }
673
674 pub fn constant<A>(mut self, value: A) -> Self
675 where
676 A: Into<GValue>,
677 {
678 self.builder = self.builder.constant(value);
679 self
680 }
681
682 pub fn emit(mut self) -> Self {
683 self.builder = self.builder.emit();
684 self
685 }
686}