use crate::graph::Graph;
use crate::search::vertex::VertexSearch;
use crate::walker::builder::{ImmutableMarker, VertexWalkerBuilder};
use crate::walker::steps::{
Detour, EdgeContext, EdgeControlFlow, EdgeFilter, EdgeReduce, EdgeTake, Edges, End, Endpoints,
VertexContext, VertexControlFlow, VertexFilter, VertexIter, VertexReduce, VertexTake, Vertices,
Waypoint,
};
use crate::{EdgeSearch, ElementId};
pub mod builder;
mod iter;
pub mod steps;
pub trait Walker<'graph>
where
Self: Sized,
{
type Graph: Graph;
type Context: Clone + 'static;
fn next_element(&mut self, graph: &'graph Self::Graph) -> Option<ElementId<Self::Graph>>;
fn ctx(&self) -> &Self::Context;
fn ctx_mut(&mut self) -> &mut Self::Context;
}
pub trait VertexWalker<'graph>: Walker<'graph> {
fn vertices_by_id<Iter>(self, vertex_ids: Iter) -> VertexIter<'graph, Self, Iter::IntoIter>
where
Iter: IntoIterator<Item = <Self::Graph as Graph>::VertexId>,
{
VertexIter::new(self, vertex_ids.into_iter())
}
fn vertices<'search>(
self,
vertex_search: VertexSearch<'search, Self::Graph>,
) -> Vertices<'search, 'graph, Self> {
Vertices::new(self, vertex_search)
}
fn filter<Predicate>(self, predicate: Predicate) -> VertexFilter<'graph, Self, Predicate>
where
Predicate: Fn(&<Self::Graph as Graph>::VertexReference<'_>, &Self::Context) -> bool,
{
VertexFilter::new(self, predicate)
}
fn control_flow<Predicate>(
self,
predicate: Predicate,
) -> VertexControlFlow<'graph, Self, Predicate>
where
Self: 'graph,
for<'a> Predicate: Fn(
&'a <Self::Graph as Graph>::VertexReference<'graph>,
&mut Self::Context,
) -> std::ops::ControlFlow<
Option<&'a <Self::Graph as Graph>::VertexReference<'graph>>,
Option<&'a <Self::Graph as Graph>::VertexReference<'graph>>,
>,
{
VertexControlFlow::new(self, predicate)
}
fn take(self, n: usize) -> VertexTake<'graph, Self> {
VertexTake::new(self, n)
}
fn detour<Path, Terminal, WalkerBuilder>(
self,
path: Path,
) -> Detour<'graph, Self, Path, Terminal>
where
Path: Fn(
VertexWalkerBuilder<
'graph,
ImmutableMarker,
Self::Graph,
Waypoint<'graph, Self::Graph, Self::Context>,
>,
) -> WalkerBuilder,
WalkerBuilder: Into<builder::WalkerBuilder<'graph, ImmutableMarker, Self::Graph, Terminal>>,
Terminal: Walker<'graph, Graph = Self::Graph>,
<Self as Walker<'graph>>::Graph: 'graph,
{
Detour::new(self, path)
}
fn context<Callback, Context>(
self,
predicate: Callback,
) -> VertexContext<'graph, Self, Callback, Context>
where
Callback: Fn(&<Self::Graph as Graph>::VertexReference<'_>, &Self::Context) -> Context,
{
VertexContext::new(self, predicate)
}
fn edges(self, search: EdgeSearch<Self::Graph>) -> Edges<'_, 'graph, Self> {
Edges::new(self, search)
}
fn reduce<Reducer>(self, reducer: Reducer) -> VertexReduce<'graph, Self, Reducer>
where
Reducer: for<'a> Fn(
&'a <Self::Graph as Graph>::VertexReference<'graph>,
&'a <Self::Graph as Graph>::VertexReference<'graph>,
&Self::Context,
) -> &'a <Self::Graph as Graph>::VertexReference<'graph>,
<Self as Walker<'graph>>::Graph: 'graph,
{
VertexReduce::new(self, reducer)
}
fn next(&mut self, graph: &'graph Self::Graph) -> Option<<Self::Graph as Graph>::VertexId>;
}
pub trait EdgeWalker<'graph>: Walker<'graph> {
fn context<Callback, Context>(
self,
predicate: Callback,
) -> EdgeContext<'graph, Self, Callback, Context>
where
Callback: Fn(&<Self::Graph as Graph>::EdgeReference<'_>, &Self::Context) -> Context,
{
EdgeContext::new(self, predicate)
}
fn filter<Predicate>(self, predicate: Predicate) -> EdgeFilter<'graph, Self, Predicate>
where
Predicate: Fn(&<Self::Graph as Graph>::EdgeReference<'_>, &Self::Context) -> bool,
{
EdgeFilter::new(self, predicate)
}
fn control_flow<Predicate>(
self,
predicate: Predicate,
) -> EdgeControlFlow<'graph, Self, Predicate>
where
Self: 'graph,
for<'a> Predicate: Fn(
&'a <Self::Graph as Graph>::EdgeReference<'graph>,
&mut Self::Context,
) -> std::ops::ControlFlow<
Option<&'a <Self::Graph as Graph>::EdgeReference<'graph>>,
Option<&'a <Self::Graph as Graph>::EdgeReference<'graph>>,
>,
{
EdgeControlFlow::new(self, predicate)
}
fn head(self) -> Endpoints<'graph, Self> {
Endpoints::new(self, End::Head)
}
fn tail(self) -> Endpoints<'graph, Self> {
Endpoints::new(self, End::Tail)
}
fn take(self, n: usize) -> EdgeTake<'graph, Self> {
EdgeTake::new(self, n)
}
fn reduce<Reducer>(self, reducer: Reducer) -> EdgeReduce<'graph, Self, Reducer>
where
Reducer: for<'a> Fn(
&'a <Self::Graph as Graph>::EdgeReference<'graph>,
&'a <Self::Graph as Graph>::EdgeReference<'graph>,
&Self::Context,
) -> &'a <Self::Graph as Graph>::EdgeReference<'graph>,
<Self as Walker<'graph>>::Graph: 'graph,
{
EdgeReduce::new(self, reducer)
}
fn next(&mut self, graph: &'graph Self::Graph) -> Option<<Self::Graph as Graph>::EdgeId>;
}