in magenta-lib/src/main/scala/magenta/graph/Graph.scala [206:238]
def traverseFrom(
node: Node[T],
traversed: Set[Edge[T]]
): Either[Error, (List[Node[T]], Set[Edge[T]])] = {
val incoming: Set[Edge[T]] = this.incoming(node)
if ((incoming -- traversed).nonEmpty) {
// if there are some incoming edges to this node that we haven't yet traversed then ignore this node - we'll be back
Right(Nil, traversed)
} else {
// if we've traversed all of the incoming edges then follow all the outgoing edges
val outgoing = this.orderedOutgoing(node)
if (outgoing.isEmpty && node != EndNode)
Left(Error(s"Node $node has no outgoing edges"))
if (outgoing.exists(traversed.contains))
Left(
Error(
s"Graph not acyclic - already traversed outgoing edges from $node"
)
)
outgoing.foldLeft[Either[Error, (List[Node[T]], Set[Edge[T]])]](
Right(List(node), traversed)
) {
case (Right((nodeAcc, edgeAcc)), successor) =>
val next = traverseFrom(successor.to, edgeAcc + successor)
next.right.map { result =>
(nodeAcc ::: result._1, edgeAcc ++ result._2)
}
case (error, _) => error
}
}
}