use itertools::Either;
use routers_network::{Edge, Entry};
use crate::CandidateId;
#[derive(Debug, Default, Copy, Clone)]
pub enum ResolutionMethod {
#[default]
Standard,
DistanceOnly,
}
#[derive(Clone, Debug)]
pub struct Reachable<E>
where
E: Entry,
{
pub source: CandidateId,
pub target: CandidateId,
pub path: Vec<Edge<E>>,
pub(crate) resolution_method: ResolutionMethod,
}
impl<E> Reachable<E>
where
E: Entry,
{
pub fn new(source: CandidateId, target: CandidateId, path: Vec<Edge<E>>) -> Self {
Self {
source,
target,
path,
resolution_method: Default::default(),
}
}
pub fn distance_only(self) -> Self {
Self {
resolution_method: ResolutionMethod::DistanceOnly,
..self
}
}
pub fn path_nodes(&self) -> impl Iterator<Item = E> {
match self.path.last() {
Some(last) => Either::Left(
self.path
.iter()
.map(|edge| edge.source)
.chain(core::iter::once(last.target)),
),
None => Either::Right(core::iter::empty()),
}
}
pub fn hash(&self) -> (usize, usize) {
(self.source.index(), self.target.index())
}
}