use crate::{
core::{GraphBase, Neighbors, VertexSet, marker::Directed},
visit::Visitor,
};
use super::{
Algo, TopoSort, TopoSortInner, algo,
dfs::{DfsVisit, dfs_visit},
kahn::kahn,
};
pub struct TopoSortBuilder<'a, G, A> {
graph: &'a G,
algo: A,
}
impl<G> TopoSort<'_, G>
where
G: GraphBase<EdgeType = Directed> + VertexSet,
{
#[doc = include_str!("../../../docs/include/algo.on.md")]
pub fn on(graph: &G) -> TopoSortBuilder<'_, G, algo::AnyAlgo> {
TopoSortBuilder {
graph,
algo: algo::AnyAlgo,
}
}
}
impl<'a, G, A> TopoSortBuilder<'a, G, A> {
pub fn dfs(self) -> TopoSortBuilder<'a, G, algo::Dfs> {
TopoSortBuilder {
graph: self.graph,
algo: algo::Dfs,
}
}
pub fn kahn(self) -> TopoSortBuilder<'a, G, algo::Kahn>
where
G: GraphBase,
{
TopoSortBuilder {
graph: self.graph,
algo: algo::Kahn,
}
}
#[doc = include_str!("../../../docs/include/algo.using.md")]
pub fn using(self, algo: Algo) -> TopoSortBuilder<'a, G, algo::SpecificAlgo>
where
G: GraphBase,
{
TopoSortBuilder {
graph: self.graph,
algo: algo::SpecificAlgo(Some(algo)),
}
}
#[doc = include_str!("../../../docs/include/algo.using_opt.md")]
pub fn using_opt(self, algo: Option<Algo>) -> TopoSortBuilder<'a, G, algo::SpecificAlgo>
where
G: GraphBase,
{
TopoSortBuilder {
graph: self.graph,
algo: algo::SpecificAlgo(algo),
}
}
}
impl<'a, G> TopoSortBuilder<'a, G, algo::AnyAlgo>
where
G: GraphBase<EdgeType = Directed> + VertexSet,
{
#[doc = include_str!("../../../docs/include/algo.run.md")]
pub fn run(self) -> TopoSort<'a, G>
where
G: Neighbors,
{
TopoSort {
inner: TopoSortInner::Kahn(kahn(self.graph)),
}
}
}
impl<'a, G> TopoSortBuilder<'a, G, algo::Dfs>
where
G: GraphBase<EdgeType = Directed> + VertexSet,
{
#[doc = include_str!("../../../docs/include/algo.run.md")]
pub fn run(self) -> DfsVisit<'a, G> {
dfs_visit(self.graph)
}
}
impl<'a, G> TopoSortBuilder<'a, G, algo::Kahn>
where
G: GraphBase<EdgeType = Directed> + VertexSet,
{
#[doc = include_str!("../../../docs/include/algo.run.md")]
pub fn run(self) -> TopoSort<'a, G>
where
G: Neighbors,
{
TopoSort {
inner: TopoSortInner::Kahn(kahn(self.graph)),
}
}
}
impl<'a, G> TopoSortBuilder<'a, G, algo::SpecificAlgo>
where
G: GraphBase<EdgeType = Directed> + VertexSet,
{
#[doc = include_str!("../../../docs/include/algo.run.md")]
pub fn run(self) -> TopoSort<'a, G>
where
G: Neighbors,
{
let inner = match self.algo.0 {
Some(Algo::Dfs) | None => {
TopoSortInner::Dfs(dfs_visit(self.graph).into_iter(self.graph))
}
Some(Algo::Kahn) => TopoSortInner::Kahn(kahn(self.graph)),
};
TopoSort { inner }
}
}