use ::{EdgeIndex, NodeIndex};
use petgraph::graph::IndexType;
use std::marker::PhantomData;
use std::ops::Index;
pub type IndexPair<Ix> = (EdgeIndex<Ix>, NodeIndex<Ix>);
pub trait Walker<G> {
type Index: IndexType;
fn next(&mut self, graph: &G) -> Option<IndexPair<Self::Index>>;
#[inline]
fn next_edge(&mut self, graph: &G) -> Option<EdgeIndex<Self::Index>> {
self.next(graph).map(|(e, _)| e)
}
#[inline]
fn next_node(&mut self, graph: &G) -> Option<NodeIndex<Self::Index>> {
self.next(graph).map(|(_, n)| n)
}
#[inline]
fn count(mut self, graph: &G) -> usize where Self: Sized {
let mut count = 0;
while let Some(_) = self.next(graph) {
count += 1;
}
count
}
#[inline]
fn last(mut self, graph: &G) -> Option<IndexPair<Self::Index>> where Self: Sized {
let mut maybe_last_pair = None;
while let Some(pair) = self.next(graph) {
maybe_last_pair = Some(pair);
}
maybe_last_pair
}
#[inline]
fn last_edge(self, graph: &G) -> Option<EdgeIndex<Self::Index>> where Self: Sized {
self.last(graph).map(|(e, _)| e)
}
#[inline]
fn last_node(self, graph: &G) -> Option<NodeIndex<Self::Index>> where Self: Sized {
self.last(graph).map(|(_, n)| n)
}
#[inline]
fn nth(mut self, graph: &G, n: usize) -> Option<IndexPair<Self::Index>>
where Self: Sized
{
(0..n+1)
.map(|_| self.next(graph))
.nth(n)
.and_then(|maybe_pair| maybe_pair)
}
#[inline]
fn nth_edge(self, graph: &G, n: usize) -> Option<EdgeIndex<Self::Index>>
where Self: Sized
{
self.nth(graph, n).map(|(e, _)| e)
}
#[inline]
fn nth_node(self, graph: &G, n: usize) -> Option<NodeIndex<Self::Index>>
where Self: Sized
{
self.nth(graph, n).map(|(_, n)| n)
}
#[inline]
fn chain<O>(self, other: O) -> Chain<G, Self::Index, Self, O>
where Self: Sized,
O: Walker<G, Index=Self::Index>,
{
Chain {
a: Some(self),
b: other,
_graph: PhantomData,
_index: PhantomData,
}
}
#[inline]
fn filter<P>(self, predicate: P) -> Filter<Self, P>
where Self: Sized,
P: FnMut(&G, EdgeIndex<Self::Index>, NodeIndex<Self::Index>) -> bool,
{
Filter {
walker: self,
predicate: predicate,
}
}
#[inline]
fn peekable(self) -> Peekable<G, Self::Index, Self> where Self: Sized {
Peekable {
walker: self,
maybe_next: None,
_graph: PhantomData,
}
}
#[inline]
fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where Self: Sized,
P: FnMut(&G, EdgeIndex<Self::Index>, NodeIndex<Self::Index>) -> bool,
{
SkipWhile {
walker: self,
maybe_predicate: Some(predicate),
}
}
#[inline]
fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where Self: Sized,
P: FnMut(&G, EdgeIndex<Self::Index>, NodeIndex<Self::Index>) -> bool,
{
TakeWhile {
maybe_walker: Some(self),
predicate: predicate,
}
}
#[inline]
fn skip(self, n: usize) -> Skip<G, Self::Index, Self> where Self: Sized {
Skip {
walker: self,
to_skip: n,
_graph: PhantomData,
_index: PhantomData,
}
}
#[inline]
fn take(self, n: usize) -> Take<G, Self::Index, Self> where Self: Sized {
Take {
walker: self,
to_take: n,
_graph: PhantomData,
_index: PhantomData,
}
}
#[inline]
fn all<P>(&mut self, graph: &G, mut predicate: P) -> bool
where P: FnMut(&G, EdgeIndex<Self::Index>, NodeIndex<Self::Index>) -> bool,
{
while let Some((e, n)) = self.next(graph) {
if !predicate(graph, e, n) {
return false;
}
}
true
}
#[inline]
fn any<P>(&mut self, graph: &G, mut predicate: P) -> bool
where P: FnMut(&G, EdgeIndex<Self::Index>, NodeIndex<Self::Index>) -> bool,
{
while let Some((e, n)) = self.next(graph) {
if predicate(graph, e, n) {
return true;
}
}
false
}
#[inline]
fn find<P>(&mut self, graph: &G, mut predicate: P) -> Option<IndexPair<Self::Index>>
where P: FnMut(&G, EdgeIndex<Self::Index>, NodeIndex<Self::Index>) -> bool
{
while let Some((e, n)) = self.next(graph) {
if predicate(graph, e, n) {
return Some((e, n));
}
}
None
}
#[inline]
fn find_edge<P>(&mut self, graph: &G, predicate: P) -> Option<EdgeIndex<Self::Index>>
where P: FnMut(&G, EdgeIndex<Self::Index>, NodeIndex<Self::Index>) -> bool
{
self.find(graph, predicate).map(|(e, _)| e)
}
#[inline]
fn find_node<P>(&mut self, graph: &G, predicate: P) -> Option<NodeIndex<Self::Index>>
where P: FnMut(&G, EdgeIndex<Self::Index>, NodeIndex<Self::Index>) -> bool
{
self.find(graph, predicate).map(|(_, n)| n)
}
#[inline]
fn cycle(self) -> Cycle<G, Self::Index, Self> where Self: Clone + Sized {
let clone = self.clone();
Cycle {
walker: self,
clone: clone,
_graph: PhantomData,
_index: PhantomData,
}
}
#[inline]
fn fold<B, F>(mut self, init: B, graph: &G, mut f: F) -> B
where Self: Sized,
F: FnMut(B, &G, EdgeIndex<Self::Index>, NodeIndex<Self::Index>) -> B
{
let mut accum = init;
while let Some((e, n)) = self.next(graph) {
accum = f(accum, graph, e, n);
}
accum
}
#[inline]
fn inspect<F>(self, f: F) -> Inspect<Self, F>
where Self: Sized,
F: FnMut(&G, EdgeIndex<Self::Index>, NodeIndex<Self::Index>),
{
Inspect {
walker: self,
f: f,
}
}
#[inline]
fn iter(self, graph: &G) -> Iter<G, Self::Index, Self>
where Self: Sized,
{
Iter {
walker: self,
graph: graph,
_index: PhantomData,
}
}
#[inline]
fn iter_weights(self, graph: &G) -> IterWeights<G, Self::Index, Self>
where Self: Sized,
{
IterWeights {
walker: self,
graph: graph,
_index: PhantomData,
}
}
}
#[derive(Clone, Debug)]
pub struct Recursive<G, Ix, F> {
next: NodeIndex<Ix>,
recursive_fn: F,
_graph: PhantomData<G>,
}
impl<G, Ix, F> Recursive<G, Ix, F> {
pub fn new(start: NodeIndex<Ix>, recursive_fn: F) -> Self
where Ix: IndexType,
F: FnMut(&G, NodeIndex<Ix>) -> Option<IndexPair<Ix>>,
{
Recursive {
next: start,
recursive_fn: recursive_fn,
_graph: PhantomData,
}
}
}
impl<G, Ix, F> Walker<G> for Recursive<G, Ix, F>
where Ix: IndexType,
F: FnMut(&G, NodeIndex<Ix>) -> Option<IndexPair<Ix>>,
{
type Index = Ix;
#[inline]
fn next(&mut self, graph: &G) -> Option<IndexPair<Ix>> {
let Recursive { ref mut next, ref mut recursive_fn, .. } = *self;
recursive_fn(graph, *next).map(|(e, n)| {
*next = n;
(e, n)
})
}
}
#[derive(Clone, Debug)]
pub struct Chain<G, Ix, A, B> {
a: Option<A>,
b: B,
_graph: PhantomData<G>,
_index: PhantomData<Ix>,
}
impl<G, Ix, A, B> Walker<G> for Chain<G, Ix, A, B>
where Ix: IndexType,
A: Walker<G, Index=Ix>,
B: Walker<G, Index=Ix>,
{
type Index = Ix;
#[inline]
fn next(&mut self, graph: &G) -> Option<IndexPair<Ix>> {
let Chain { ref mut a, ref mut b, .. } = *self;
match a.as_mut().and_then(|walker| walker.next(graph)) {
Some(step) => Some(step),
None => {
*a = None;
b.next(graph)
},
}
}
}
#[derive(Clone, Debug)]
pub struct Filter<W, P> {
walker: W,
predicate: P,
}
impl<G, Ix, W, P> Walker<G> for Filter<W, P>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
P: FnMut(&G, EdgeIndex<Ix>, NodeIndex<Ix>) -> bool,
{
type Index = Ix;
#[inline]
fn next(&mut self, graph: &G) -> Option<IndexPair<Ix>> {
while let Some((e, n)) = self.walker.next(graph) {
if (self.predicate)(graph, e, n) {
return Some((e, n));
}
}
None
}
}
#[derive(Clone, Debug)]
pub struct Peekable<G, Ix, W> where Ix: IndexType {
walker: W,
maybe_next: Option<IndexPair<Ix>>,
_graph: PhantomData<G>,
}
impl<G, Ix, W> Peekable<G, Ix, W>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
{
#[inline]
pub fn peek(&mut self, graph: &G) -> Option<IndexPair<Ix>> {
self.maybe_next.or_else(|| {
self.maybe_next = self.walker.next(graph);
self.maybe_next
})
}
#[inline]
pub fn peek_edge(&mut self, graph: &G) -> Option<EdgeIndex<Ix>> {
self.peek(graph).map(|(e, _)| e)
}
#[inline]
pub fn peek_node(&mut self, graph: &G) -> Option<NodeIndex<Ix>> {
self.peek(graph).map(|(_, n)| n)
}
}
impl<G, Ix, W> Walker<G> for Peekable<G, Ix, W>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
{
type Index = Ix;
#[inline]
fn next(&mut self, graph: &G) -> Option<IndexPair<Ix>> {
self.maybe_next.take().or_else(|| {
self.walker.next(graph)
})
}
}
#[derive(Clone, Debug)]
pub struct SkipWhile<W, P> {
walker: W,
maybe_predicate: Option<P>,
}
impl<G, Ix, W, P> Walker<G> for SkipWhile<W, P>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
P: FnMut(&G, EdgeIndex<Ix>, NodeIndex<Ix>) -> bool,
{
type Index = Ix;
#[inline]
fn next(&mut self, graph: &G) -> Option<IndexPair<Ix>> {
match self.maybe_predicate.take() {
Some(mut predicate) => {
while let Some((e, n)) = self.walker.next(graph) {
if !predicate(graph, e, n) {
return Some((e, n));
}
}
None
},
None => self.walker.next(graph),
}
}
}
#[derive(Clone, Debug)]
pub struct TakeWhile<W, P> {
maybe_walker: Option<W>,
predicate: P,
}
impl<G, Ix, W, P> Walker<G> for TakeWhile<W, P>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
P: FnMut(&G, EdgeIndex<Ix>, NodeIndex<Ix>) -> bool,
{
type Index = Ix;
#[inline]
fn next(&mut self, graph: &G) -> Option<IndexPair<Ix>> {
let TakeWhile { ref mut maybe_walker, ref mut predicate } = *self;
let maybe_next_idx_pair = maybe_walker.as_mut().and_then(|walker| walker.next(graph));
if let Some((e, n)) = maybe_next_idx_pair {
if predicate(graph, e, n) {
return Some((e, n));
} else {
*maybe_walker = None;
}
}
None
}
}
#[derive(Clone, Debug)]
pub struct Skip<G, Ix, W> {
walker: W,
to_skip: usize,
_graph: PhantomData<G>,
_index: PhantomData<Ix>,
}
impl<G, Ix, W> Walker<G> for Skip<G, Ix, W>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
{
type Index = Ix;
#[inline]
fn next(&mut self, graph: &G) -> Option<IndexPair<Ix>> {
if self.to_skip > 0 {
for _ in 0..self.to_skip {
self.walker.next(graph);
}
self.to_skip = 0;
}
self.walker.next(graph)
}
}
#[derive(Clone, Debug)]
pub struct Take<G, Ix, W> {
walker: W,
to_take: usize,
_graph: PhantomData<G>,
_index: PhantomData<Ix>,
}
impl<G, Ix, W> Walker<G> for Take<G, Ix, W>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
{
type Index = Ix;
#[inline]
fn next(&mut self, graph: &G) -> Option<IndexPair<Ix>> {
if self.to_take > 0 {
self.to_take -= 1;
self.walker.next(graph)
} else {
None
}
}
}
#[derive(Clone, Debug)]
pub struct Cycle<G, Ix, W> {
walker: W,
clone: W,
_graph: PhantomData<G>,
_index: PhantomData<Ix>,
}
impl<G, Ix, W> Walker<G> for Cycle<G, Ix, W>
where Ix: IndexType,
W: Walker<G, Index=Ix> + Clone,
{
type Index = Ix;
#[inline]
fn next(&mut self, graph: &G) -> Option<IndexPair<Ix>> {
self.clone.next(graph).or_else(|| {
self.clone = self.walker.clone();
self.clone.next(graph)
})
}
}
#[derive(Clone, Debug)]
pub struct Inspect<W, F> {
walker: W,
f: F,
}
impl<G, Ix, W, F> Walker<G> for Inspect<W, F>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
F: FnMut(&G, EdgeIndex<Ix>, NodeIndex<Ix>),
{
type Index = Ix;
#[inline]
fn next(&mut self, graph: &G) -> Option<IndexPair<Ix>> {
self.walker.next(graph).map(|(e, n)| {
(self.f)(graph, e, n);
(e, n)
})
}
}
#[derive(Clone, Debug)]
pub struct Iter<'a, G: 'a, Ix, W> {
graph: &'a G,
walker: W,
_index: PhantomData<Ix>,
}
impl<'a, G, Ix, W> Iter<'a, G, Ix, W> {
#[inline]
pub fn edges(self) -> IterEdges<'a, G, Ix, W> {
let Iter { graph, walker, .. } = self;
IterEdges {
graph: graph,
walker: walker,
_index: PhantomData,
}
}
#[inline]
pub fn nodes(self) -> IterNodes<'a, G, Ix, W> {
let Iter { graph, walker, .. } = self;
IterNodes {
graph: graph,
walker: walker,
_index: PhantomData,
}
}
}
impl<'a, G, Ix, W> Iterator for Iter<'a, G, Ix, W>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
{
type Item = IndexPair<Ix>;
#[inline]
fn next(&mut self) -> Option<IndexPair<Ix>> {
let Iter { ref mut walker, ref graph, .. } = *self;
walker.next(graph)
}
}
#[derive(Clone, Debug)]
pub struct IterEdges<'a, G: 'a, Ix, W> {
graph: &'a G,
walker: W,
_index: PhantomData<Ix>,
}
impl<'a, G, Ix, W> Iterator for IterEdges<'a, G, Ix, W>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
{
type Item = EdgeIndex<Ix>;
#[inline]
fn next(&mut self) -> Option<EdgeIndex<Ix>> {
let IterEdges { ref mut walker, ref graph, .. } = *self;
walker.next_edge(graph)
}
}
#[derive(Clone, Debug)]
pub struct IterNodes<'a, G: 'a, Ix, W> {
graph: &'a G,
walker: W,
_index: PhantomData<Ix>,
}
impl<'a, G, Ix, W> Iterator for IterNodes<'a, G, Ix, W>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
{
type Item = NodeIndex<Ix>;
#[inline]
fn next(&mut self) -> Option<NodeIndex<Ix>> {
let IterNodes { ref mut walker, ref graph, .. } = *self;
walker.next_node(graph)
}
}
#[derive(Clone, Debug)]
pub struct IterWeights<'a, G: 'a, Ix, W> {
graph: &'a G,
walker: W,
_index: PhantomData<Ix>,
}
impl<'a, G, Ix, W> IterWeights<'a, G, Ix, W> {
pub fn edges(self) -> IterEdgeWeights<'a, G, Ix, W> {
let IterWeights { graph, walker, .. } = self;
IterEdgeWeights {
graph: graph,
walker: walker,
_index: PhantomData,
}
}
pub fn nodes(self) -> IterNodeWeights<'a, G, Ix, W> {
let IterWeights { graph, walker, .. } = self;
IterNodeWeights {
graph: graph,
walker: walker,
_index: PhantomData,
}
}
}
impl<'a, G, Ix, W> Iterator for IterWeights<'a, G, Ix, W>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
G: Index<EdgeIndex<Ix>>,
G: Index<NodeIndex<Ix>>,
{
type Item = (&'a <G as Index<EdgeIndex<Ix>>>::Output, &'a <G as Index<NodeIndex<Ix>>>::Output);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let IterWeights { ref mut walker, ref graph, .. } = *self;
walker.next(graph).map(|(e, n)| (&graph[e], &graph[n]))
}
}
#[derive(Clone, Debug)]
pub struct IterEdgeWeights<'a, G: 'a, Ix, W> {
graph: &'a G,
walker: W,
_index: PhantomData<Ix>,
}
impl<'a, G, Ix, W> Iterator for IterEdgeWeights<'a, G, Ix, W>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
G: Index<EdgeIndex<Ix>>,
{
type Item = &'a <G as Index<EdgeIndex<Ix>>>::Output;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let IterEdgeWeights { ref mut walker, ref graph, .. } = *self;
walker.next_edge(graph).map(|e| &graph[e])
}
}
#[derive(Clone, Debug)]
pub struct IterNodeWeights<'a, G: 'a, Ix, W> {
graph: &'a G,
walker: W,
_index: PhantomData<Ix>,
}
impl<'a, G, Ix, W> Iterator for IterNodeWeights<'a, G, Ix, W>
where Ix: IndexType,
W: Walker<G, Index=Ix>,
G: Index<NodeIndex<Ix>>,
{
type Item = &'a <G as Index<NodeIndex<Ix>>>::Output;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let IterNodeWeights { ref mut walker, ref graph, .. } = *self;
walker.next_node(graph).map(|n| &graph[n])
}
}