use super::*;
use std::iter::FromIterator;
pub trait Vertex: Copy + Eq{}
impl<T> Vertex for T
where T: Copy + Eq
{}
pub trait Weight: Copy + Eq{}
impl<T> Weight for T
where T: Copy + Eq
{}
pub trait VertexIter<V>: IntoIterator<Item=V> + FromIterator<V>
where
V: Vertex,
Self::IntoIter : ExactSizeIterator<Item=V>
{}
impl<T,V> VertexIter<V> for T
where
T: IntoIterator<Item=V> + FromIterator<V>,
T::IntoIter: ExactSizeIterator<Item=V>,
V: Vertex,
{}
pub trait EdgeIter<V,W>: IntoIterator<Item=BaseEdge<V,W>> + FromIterator<BaseEdge<V,W>>
where
V: Vertex,
W: Weight,
Self::IntoIter : ExactSizeIterator<Item=BaseEdge<V,W>>
{}
impl<T,V,W> EdgeIter<V,W> for T
where
T: IntoIterator<Item=BaseEdge<V,W>> + FromIterator<BaseEdge<V,W>>,
T::IntoIter: ExactSizeIterator<Item=BaseEdge<V,W>>,
V: Vertex,
W: Weight,
{}
pub trait BaseGraph
where
<Self::VertexIter as IntoIterator>::IntoIter: ExactSizeIterator,
<Self::EdgeIter as IntoIterator>::IntoIter: ExactSizeIterator,
{
type Vertex: Vertex;
type Weight: Weight;
type VertexIter: VertexIter<Self::Vertex>;
type EdgeIter: EdgeIter<Self::Vertex, Self::Weight>;
fn empty_graph() -> Self;
fn all_vertices(&self) -> Self::VertexIter;
fn all_edges(&self) -> Self::EdgeIter;
fn add_vertex(&mut self, v: Self::Vertex) -> Result<(),()>;
fn remove_vertex(&mut self, v: Self::Vertex) -> Result<(),()>;
fn add_edge(&mut self, e: BaseEdge<Self::Vertex,Self::Weight>) -> Result<(),()>;
fn remove_edge(&mut self, e: BaseEdge<Self::Vertex,Self::Weight>) -> Result<(),()>;
fn vertex_count(&self) -> usize {
self.all_vertices().into_iter().len()
}
fn edge_count(&self) -> usize {
self.all_edges().into_iter().len()
}
fn graph( vertices: Vec<Self::Vertex>,
edges: Vec<(Self::Vertex, Self::Vertex,Self::Weight)>)
-> Result<Self,()>
where
Self: Sized,
{
let mut g = Self::empty_graph();
for v in vertices {
g.add_vertex(v)?;
}
for (so,si,w) in edges {
g.add_edge(BaseEdge::new(so,si,w))?;
}
Ok(g)
}
fn edges_between(&self, v1: Self::Vertex, v2: Self::Vertex) -> Self::EdgeIter
{
let all_edges = self.all_edges().into_iter();
let relevant = all_edges.filter(|edge|{
(edge.source == v1 && edge.sink == v2) ||
(edge.source == v2 && edge.sink == v1)
});
relevant.collect()
}
fn edges_sourced_in(&self, v: Self::Vertex) -> Self::EdgeIter
{
self.all_edges().into_iter().filter(|e| e.source() == v).collect::<Self::EdgeIter>()
}
fn edges_sinked_in(&self, v: Self::Vertex) -> Self::EdgeIter
{
self.all_edges().into_iter().filter(|e| e.sink() == v).collect::<Self::EdgeIter>()
}
}