gremlin_client/process/traversal/
graph_traversal.rs

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}