use std::ops::Deref;
use derive_where::derive_where;
use crate::{RelRc, RelWeak};
#[derive(Debug)]
#[derive_where(Clone; E)]
pub struct InnerEdgeData<N, E> {
pub(crate) value: E,
pub(crate) source: RelRc<N, E>,
pub(crate) target: RelWeak<N, E>,
}
impl<N, E> InnerEdgeData<N, E> {
pub(crate) fn new(value: E, source: RelRc<N, E>, target: RelWeak<N, E>) -> Self {
Self {
value,
source,
target,
}
}
pub fn value(&self) -> &E {
&self.value
}
pub fn source(&self) -> &RelRc<N, E> {
&self.source
}
pub(crate) fn downgrade(&self, target_pos: usize) -> WeakEdge<N, E> {
WeakEdge::new(target_pos, self.target.clone())
}
}
impl<N, E> InnerEdgeData<N, E> {
pub fn target(&self) -> RelRc<N, E> {
self.target
.upgrade()
.expect("target node is no longer alive")
}
}
#[derive(Debug)]
#[derive_where(Clone)]
pub struct WeakEdge<N, E> {
pub(crate) index: usize,
pub(crate) target: RelWeak<N, E>,
}
impl<N, E> WeakEdge<N, E> {
pub(crate) fn new(index: usize, target: RelWeak<N, E>) -> Self {
Self { index, target }
}
pub fn ptr_eq(&self, other: &Self) -> bool {
self.index == other.index && RelWeak::ptr_eq(&self.target, &other.target)
}
pub fn target(&self) -> &RelWeak<N, E> {
&self.target
}
}
#[derive(Debug)]
#[derive_where(Clone)]
pub struct Edge<N, E> {
pub(crate) index: usize,
pub(crate) target: RelRc<N, E>,
}
impl<N, E> Edge<N, E> {
pub fn target(&self) -> &RelRc<N, E> {
&self.target
}
pub fn into_target(self) -> RelRc<N, E> {
self.target
}
}
impl<N, E> Deref for Edge<N, E> {
type Target = InnerEdgeData<N, E>;
fn deref(&self) -> &Self::Target {
self.target.incoming(self.index).unwrap()
}
}
impl<N, E> WeakEdge<N, E> {
pub fn upgrade(&self) -> Option<Edge<N, E>> {
let target = self.target.upgrade()?;
Some(Edge {
index: self.index,
target,
})
}
}