use std::borrow::Cow;
use anyhow::Result;
use crate::{EdgeID, Edges, NodeID, Nodes, VisitableGraph};
#[derive(Debug, Clone)]
pub struct ReversedGraph<Inner>
where Inner: VisitableGraph
{
graph: Inner
}
impl<Inner> ReversedGraph<Inner>
where Inner: VisitableGraph
{
pub fn new(graph: Inner) -> Self {
ReversedGraph { graph }
}
pub fn graph(&self) -> &Inner {
&self.graph
}
}
impl<Inner> VisitableGraph for ReversedGraph<Inner>
where Inner: VisitableGraph
{
type GData = Inner::GData;
type NData = Inner::NData;
type EData = Inner::EData;
fn data(&self) -> &Self::GData {
self.graph.data()
}
fn node_data(&self, id: impl AsRef<NodeID>) -> Result<Cow<'static, Self::NData>> {
self.graph.node_data(id)
}
fn edge_data(&self, id: impl AsRef<EdgeID>) -> Result<Cow<'static, Self::EData>> {
self.graph.edge_data(id)
}
fn is_empty(&self) -> bool {
self.graph.is_empty()
}
fn node_count(&self) -> usize {
self.graph.node_count()
}
fn edge_count(&self) -> usize {
self.graph.edge_count()
}
fn all_nodes(&self) -> Nodes {
self.graph.all_nodes()
}
fn all_edges(&self) -> Edges {
self.graph.all_edges()
}
fn has_node(&self, id: impl AsRef<NodeID>) -> bool {
self.graph.has_node(id)
}
fn has_edge(&self, id: impl AsRef<EdgeID>) -> bool {
self.graph.has_edge(id)
}
fn has_edge_from_to(&self, source: impl AsRef<NodeID>, target: impl AsRef<NodeID>) -> bool {
self.graph.has_edge_from_to(target, source)
}
fn has_edge_between(&self, a: impl AsRef<NodeID>, b: impl AsRef<NodeID>) -> bool {
self.graph.has_edge_between(a, b)
}
fn source(&self, id: impl AsRef<EdgeID>) -> Result<NodeID> {
self.graph.target(id)
}
fn target(&self, id: impl AsRef<EdgeID>) -> Result<NodeID> {
self.graph.source(id)
}
fn endpoints(&self, id: impl AsRef<EdgeID>) -> Result<(NodeID, NodeID)> {
let (a, b) = self.graph.endpoints(id)?;
Ok((b, a))
}
fn out_edges(&self, id: impl AsRef<NodeID>) -> Result<Edges> {
self.graph.in_edges(id)
}
fn in_edges(&self, id: impl AsRef<NodeID>) -> Result<Edges> {
self.graph.out_edges(id)
}
fn incident_edges(&self, id: impl AsRef<NodeID>) -> Result<Edges> {
self.graph.incident_edges(id)
}
fn out_degree(&self, id: impl AsRef<NodeID>) -> Result<usize> {
self.graph.in_degree(id)
}
fn in_degree(&self, id: impl AsRef<NodeID>) -> Result<usize> {
self.graph.out_degree(id)
}
fn degree(&self, id: impl AsRef<NodeID>) -> Result<usize> {
self.graph.degree(id)
}
fn successors(&self, id: impl AsRef<NodeID>) -> Result<Nodes> {
self.graph.predecessors(id)
}
fn predecessors(&self, id: impl AsRef<NodeID>) -> Result<Nodes> {
self.graph.successors(id)
}
fn neighbors(&self, id: impl AsRef<NodeID>) -> Result<Nodes> {
self.graph.neighbors(id)
}
fn has_successors(&self, id: impl AsRef<NodeID>) -> Result<bool> {
self.graph.has_predecessors(id)
}
fn has_predecessors(&self, id: impl AsRef<NodeID>) -> Result<bool> {
self.graph.has_successors(id)
}
fn has_neighbors(&self, id: impl AsRef<NodeID>) -> Result<bool> {
self.graph.has_neighbors(id)
}
fn all_roots(&self) -> Nodes {
self.graph.all_leaves()
}
fn all_leaves(&self) -> Nodes {
self.graph.all_roots()
}
fn non_roots(&self) -> Nodes {
self.graph.non_leaves()
}
fn non_leaves(&self) -> Nodes {
self.graph.non_roots()
}
fn all_internals(&self) -> Nodes {
self.graph.all_internals()
}
fn is_leaf(&self, id: impl AsRef<NodeID>) -> Result<bool> {
self.graph.is_root(id)
}
fn is_root(&self, id: impl AsRef<NodeID>) -> Result<bool> {
self.graph.is_leaf(id)
}
fn is_internal(&self, id: impl AsRef<NodeID>) -> Result<bool> {
self.graph.is_internal(id)
}
}