use crate::{EdgeId, IdType, NodeId};
pub trait Graph<N, E> {
type NodeIdIterator: Iterator<Item = NodeId>;
type EdgeIdIterator: Iterator<Item = EdgeId>;
fn node_len(&self) -> IdType;
fn edge_len(&self) -> IdType;
fn node_id_iter(&self) -> Self::NodeIdIterator;
fn edge_id_iter(&self) -> Self::EdgeIdIterator;
fn node_data(&self, id: NodeId) -> &N;
fn edge_data(&self, id: EdgeId) -> &E;
fn edge(&self, id: EdgeId) -> EdgeRef<E>;
fn edge_start(&self, id: EdgeId) -> NodeId;
fn edge_end(&self, id: EdgeId) -> NodeId;
fn is_node_id_valid(&self, id: NodeId) -> bool;
fn is_edge_id_valid(&self, id: EdgeId) -> bool;
}
pub trait ForwardNavigableGraph<'a, N, E>: Graph<N, E> {
type OutEdgeIterator: Iterator<Item = EdgeId> + 'a;
fn out_edges(&self, id: NodeId) -> Self::OutEdgeIterator;
}
pub trait BackwardNavigableGraph<'a, N, E>: Graph<N, E> {
type InEdgeIterator: Iterator<Item = EdgeId> + 'a;
fn in_edges(&self, id: NodeId) -> Self::InEdgeIterator;
}
pub trait MutableGraph<N, E> {
fn new() -> Self;
fn add_node(&mut self, node: Node<N>) -> NodeId;
fn add_edge(&mut self, edge: Edge<E>) -> Result<EdgeId, GraphModificationError>;
}
#[derive(Debug)]
pub enum GraphModificationError {
StartNodeDoesNotExist,
EndNodeDoesNotExist,
}
#[derive(Debug)]
pub struct Node<N> {
data: N,
}
#[derive(Debug)]
pub struct Edge<E> {
start: NodeId,
end: NodeId,
data: E,
}
#[derive(Debug, Eq, PartialEq)]
pub struct NodeRef<'a, N> {
data: &'a N,
}
#[derive(Debug, Eq, PartialEq)]
pub struct EdgeRef<'a, E> {
start: NodeId,
end: NodeId,
data: &'a E,
}
impl<N> Node<N> {
pub fn new(data: N) -> Self {
Self { data }
}
pub fn data(&self) -> &N {
&self.data
}
}
impl<E> Edge<E> {
pub fn new(start: NodeId, end: NodeId, data: E) -> Self {
Self { start, end, data }
}
pub fn start(&self) -> NodeId {
self.start
}
pub fn end(&self) -> NodeId {
self.end
}
pub fn data(&self) -> &E {
&self.data
}
}
impl<'a, N> NodeRef<'a, N> {
pub fn new(data: &'a N) -> Self {
Self { data }
}
pub fn data(&self) -> &'a N {
self.data
}
}
impl<'a, E> EdgeRef<'a, E> {
pub fn new(start: NodeId, end: NodeId, data: &'a E) -> Self {
Self { start, end, data }
}
pub fn start(&self) -> NodeId {
self.start
}
pub fn end(&self) -> NodeId {
self.end
}
pub fn data(&self) -> &'a E {
self.data
}
}
impl<'a, E> From<&'a Edge<E>> for EdgeRef<'a, E> {
fn from(edge: &'a Edge<E>) -> Self {
EdgeRef::new(edge.start(), edge.end(), edge.data())
}
}
impl<'a, E: Clone> From<&EdgeRef<'a, E>> for Edge<E> {
fn from(edge: &EdgeRef<'a, E>) -> Self {
Edge::new(edge.start(), edge.end(), edge.data().clone())
}
}
impl<'a, E: Clone> From<EdgeRef<'a, E>> for Edge<E> {
fn from(edge: EdgeRef<'a, E>) -> Self {
Edge::from(&edge)
}
}