mod dfs;
mod entity_graph;
mod scc;
use core::{fmt, iter};
pub use dfs::*;
pub use entity_graph::*;
pub use scc::*;
use crate::prelude::*;
pub trait Graph<Node> {
type NodesIter<'a>: Iterator<Item = Node>
where
Self: 'a;
fn nodes(&self) -> Self::NodesIter<'_>;
type SuccessorsIter<'a>: Iterator<Item = Node>
where
Self: 'a;
fn successors(&self, node: Node) -> Self::SuccessorsIter<'_>;
fn by_ref(&self) -> &Self {
self
}
fn filter_nodes<F>(self, predicate: F) -> FilterNodes<Self, F>
where
Self: Sized,
F: Fn(&Node) -> bool,
{
FilterNodes {
graph: self,
predicate,
}
}
}
impl<T, Node> Graph<Node> for &'_ T
where
T: ?Sized + Graph<Node>,
{
type NodesIter<'a>
= T::NodesIter<'a>
where
Self: 'a;
fn nodes(&self) -> Self::NodesIter<'_> {
(*self).nodes()
}
type SuccessorsIter<'a>
= T::SuccessorsIter<'a>
where
Self: 'a;
fn successors(&self, node: Node) -> Self::SuccessorsIter<'_> {
(*self).successors(node)
}
}
pub struct FilterNodes<G, F> {
graph: G,
predicate: F,
}
impl<G, F> fmt::Debug for FilterNodes<G, F>
where
G: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Filter")
.field("graph", &self.graph)
.field("predicate", &"..")
.finish()
}
}
impl<G, F, Node> Graph<Node> for FilterNodes<G, F>
where
G: Graph<Node>,
F: Fn(&Node) -> bool,
{
type NodesIter<'a>
= iter::Filter<G::NodesIter<'a>, &'a F>
where
Self: 'a;
fn nodes(&self) -> Self::NodesIter<'_> {
self.graph.nodes().filter(&self.predicate)
}
type SuccessorsIter<'a>
= iter::Filter<G::SuccessorsIter<'a>, &'a F>
where
Self: 'a;
fn successors(&self, node: Node) -> Self::SuccessorsIter<'_> {
self.graph.successors(node).filter(&self.predicate)
}
}
fn extend_with_range<T>(
dest: &mut Vec<T>,
items: impl IntoIterator<Item = T>,
) -> core::ops::Range<u32> {
let start = dest.len();
let start = u32::try_from(start).unwrap();
dest.extend(items);
let end = dest.len();
let end = u32::try_from(end).unwrap();
start..end
}