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