use core::hint::unreachable_unchecked;
pub struct GraphIterRes<E, T> {
pub values : E,
pub ptr : T,
}
pub struct EdgeBoth<N, E> {
pub this : N,
pub that : N,
pub edge : E
}
pub struct EdgeLoop<N, E> {
pub this : N,
pub edge : E
}
pub enum Edge<N, E> {
Both(EdgeBoth<N, E>),
Loop(EdgeLoop<N, E>),
}
pub use crate::Edge::Both;
pub use crate::Edge::Loop;
pub trait OptionEdge<N, E> {
fn this(self) -> Option<EdgeLoop<N, E>>;
fn that(self) -> Option<EdgeLoop<N, E>>;
fn both(self) -> Option<EdgeBoth<N, E>>;
fn edge(self) -> Option<E>;
unsafe fn both_unchecked(self) -> Option<EdgeBoth<N, E>>;
}
impl <N, E> OptionEdge<N, E> for Option<Edge<N, E>>
{
fn this(self) -> Option<EdgeLoop<N, E>> {
self.map(|x| {
x.this()
})
}
fn that(self) -> Option<EdgeLoop<N, E>> {
self.map(|x| {
x.that()
})
}
fn both(self) -> Option<EdgeBoth<N, E>> {
match self {
Some(s) => s.both(),
_ => None,
}
}
unsafe fn both_unchecked(self) -> Option<EdgeBoth<N, E>> {
self.map(|x| {
x.both_unchecked()
})
}
fn edge(self) -> Option<E> {
self.map(|x| {
x.edge()
})
}
}
impl <N, E> Edge<N, E> {
pub fn this(self) -> EdgeLoop<N, E>
{
match self {
Both(s) => EdgeLoop { this : s.this, edge : s.edge },
Loop(s) => s,
}
}
pub fn that(self) -> EdgeLoop<N, E>
{
match self {
Both(s) => EdgeLoop { this : s.that, edge : s.edge },
Loop(s) => s,
}
}
pub fn both(self) -> Option<EdgeBoth<N, E>>
{
match self {
Both(s) => Some(s),
_ => None,
}
}
pub unsafe fn both_unchecked(self) -> EdgeBoth<N, E>
{
match self {
Both(s) => s,
_ => unreachable_unchecked(),
}
}
pub fn edge(self) -> E
{
self.this().edge
}
}