#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SearchOutcome<P, S> {
Found {
path: P,
stats: S,
},
NoPath {
stats: S,
},
}
impl<P, S> SearchOutcome<P, S> {
#[must_use]
pub const fn found(path: P, stats: S) -> Self {
Self::Found { path, stats }
}
#[must_use]
pub const fn no_path(stats: S) -> Self {
Self::NoPath { stats }
}
#[must_use]
pub const fn is_found(&self) -> bool {
matches!(self, Self::Found { .. })
}
#[must_use]
pub const fn path(&self) -> Option<&P> {
match self {
Self::Found { path, .. } => Some(path),
Self::NoPath { .. } => None,
}
}
#[must_use]
pub const fn stats(&self) -> &S {
match self {
Self::Found { stats, .. } | Self::NoPath { stats } => stats,
}
}
}
pub trait SearchPathCost {
type Cost;
fn path_cost(&self) -> Self::Cost;
}
pub trait SearchVisitStats {
fn visited_nodes(&self) -> usize;
}
impl<P, S> SearchOutcome<P, S>
where
P: SearchPathCost,
{
#[must_use]
pub fn cost(&self) -> Option<P::Cost> {
self.path().map(SearchPathCost::path_cost)
}
}
impl<P, S> SearchOutcome<P, S>
where
S: SearchVisitStats,
{
#[must_use]
pub fn visited_nodes(&self) -> usize {
self.stats().visited_nodes()
}
}