@@ -46,6 +46,42 @@ class PathAwareTraversal[+A](val elementsWithPath: IterableOnce[(A, Vector[Any])
46
46
override def dedupBy (fun : A => Any ): Traversal [A ] =
47
47
new PathAwareTraversal (elementsWithPathIterator.distinctBy(x => fun(x._1)))
48
48
49
+ override def union [B ](traversals : (Traversal [A ] => Traversal [B ])* ): Traversal [B ] =
50
+ new PathAwareTraversal (elementsWithPathIterator.flatMap { case (a, p) =>
51
+ traversals.iterator.flatMap { inner =>
52
+ inner(new PathAwareTraversal (Iterator .single((a, p)))) match {
53
+ case stillPathAware : PathAwareTraversal [B ] => stillPathAware.elementsWithPathIterator
54
+ // do we really want to allow the following, or is it an error?
55
+ case notPathAware => notPathAware.iterator.map { (b : B ) => (b, p.appended(a)) }
56
+ }
57
+ }
58
+ })
59
+
60
+
61
+ override def choose [BranchOn >: Null , NewEnd ]
62
+ (on : Traversal [A ] => Traversal [BranchOn ])
63
+ (options : PartialFunction [BranchOn , Traversal [A ] => Traversal [NewEnd ]]): Traversal [NewEnd ] =
64
+ new PathAwareTraversal (elementsWithPathIterator.flatMap { case (a, p) =>
65
+ val branchOnValue : BranchOn = on(Traversal .fromSingle(a)).headOption.getOrElse(null )
66
+ options.applyOrElse(branchOnValue, (failState : BranchOn ) => ((unused : Traversal [A ]) => Traversal .empty[NewEnd ])).apply(new PathAwareTraversal (Iterator .single((a, p)))) match {
67
+ case stillPathAware : PathAwareTraversal [NewEnd ] => stillPathAware.elementsWithPathIterator
68
+ // do we really want to allow the following, or is it an error?
69
+ case notPathAware => notPathAware.iterator.map { (b : NewEnd ) => (b, p.appended(a)) }
70
+ }
71
+ })
72
+
73
+ override def coalesce [NewEnd ](options : (Traversal [A ] => Traversal [NewEnd ])* ): Traversal [NewEnd ] =
74
+ new PathAwareTraversal (elementsWithPathIterator.flatMap { case (a, p) =>
75
+ options.iterator.map { inner =>
76
+ inner(new PathAwareTraversal (Iterator .single((a, p)))) match {
77
+ case stillPathAware : PathAwareTraversal [NewEnd ] => stillPathAware.elementsWithPathIterator
78
+ // do we really want to allow the following, or is it an error?
79
+ case notPathAware => notPathAware.iterator.map { (b : NewEnd ) => (b, p.appended(a)) }
80
+ }
81
+ }.find(_.nonEmpty).getOrElse(Iterator .empty)
82
+ })
83
+
84
+
49
85
// TODO add type safety once we're on dotty, similar to gremlin-scala's as/label steps with typelevel append?
50
86
override def path : Traversal [Vector [Any ]] =
51
87
new Traversal (elementsWithPathIterator.map {
@@ -82,8 +118,8 @@ class PathAwareTraversal[+A](val elementsWithPath: IterableOnce[(A, Vector[Any])
82
118
val behaviour = behaviourBuilder(new RepeatBehaviour .Builder [B ]).build
83
119
val _repeatTraversal = repeatTraversal.asInstanceOf [Traversal [B ] => Traversal [B ]] // this cast usually :tm: safe, because `B` is a supertype of `A`
84
120
val repeat0 : B => PathAwareTraversal [B ] = PathAwareRepeatStep (_repeatTraversal, behaviour)
85
- new PathAwareTraversal (iterator .flatMap { a =>
86
- repeat0(a).elementsWithPath
121
+ new PathAwareTraversal (elementsWithPathIterator .flatMap { case (a,p) =>
122
+ repeat0(a).elementsWithPathIterator.map{ case (b, pp) => (b, p ++ pp)}
87
123
})
88
124
}
89
125
0 commit comments