use super::{Chain, ChainFeatures};
use crate::LPR;
use crate::triad::DynTriad;
use alloc::vec::Vec;
use rshyper::EdgeId;
#[derive(Clone, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Visited<T = isize, Ix = usize> {
pub(crate) chain: Chain,
pub(crate) edges: Vec<EdgeId<Ix>>,
pub(crate) visited: Vec<DynTriad<T>>,
}
impl<T, Ix> Visited<T, Ix> {
pub fn new(path: Vec<LPR>, visited: Vec<DynTriad<T>>) -> Self {
Visited {
chain: Chain::from_path(path),
edges: Vec::new(),
visited,
}
}
pub fn from_visited<I>(visited: I) -> Self
where
I: IntoIterator<Item = DynTriad<T>>,
{
let visited = Vec::from_iter(visited);
Visited::new(Vec::new(), visited)
}
pub const fn chain(&self) -> &Chain {
&self.chain
}
pub const fn chain_mut(&mut self) -> &mut Chain {
&mut self.chain
}
pub const fn cost(&self) -> usize {
self.chain().cost()
}
pub const fn features(&self) -> &ChainFeatures {
self.chain().features()
}
pub const fn edges(&self) -> &Vec<EdgeId<Ix>> {
&self.edges
}
pub const fn path(&self) -> &Vec<LPR> {
self.chain().path()
}
pub const fn visited(&self) -> &Vec<DynTriad<T>> {
&self.visited
}
pub fn iter_path(&self) -> impl Iterator<Item = &LPR> {
self.path().iter()
}
}
impl<T, Ix> AsRef<Chain> for Visited<T, Ix> {
fn as_ref(&self) -> &Chain {
self.chain()
}
}
impl<T, Ix> AsMut<Chain> for Visited<T, Ix> {
fn as_mut(&mut self) -> &mut Chain {
self.chain_mut()
}
}
impl<T, Ix> core::borrow::Borrow<Chain> for Visited<T, Ix> {
fn borrow(&self) -> &Chain {
self.chain()
}
}
impl<T, Ix> core::borrow::BorrowMut<Chain> for Visited<T, Ix> {
fn borrow_mut(&mut self) -> &mut Chain {
self.chain_mut()
}
}
impl<T, Ix> core::ops::Deref for Visited<T, Ix> {
type Target = Chain;
fn deref(&self) -> &Self::Target {
self.chain()
}
}
impl<T, Ix> core::ops::DerefMut for Visited<T, Ix> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.chain_mut()
}
}
impl<T, Ix> IntoIterator for Visited<T, Ix> {
type Item = LPR;
type IntoIter = alloc::vec::IntoIter<LPR>;
fn into_iter(self) -> Self::IntoIter {
self.chain.into_iter()
}
}
impl<'a, T, Ix> IntoIterator for &'a Visited<T, Ix> {
type Item = &'a LPR;
type IntoIter = core::slice::Iter<'a, LPR>;
fn into_iter(self) -> Self::IntoIter {
self.chain.path.iter()
}
}