use crate::{
error::RemoveNodeError,
graph::Node,
map::{MapWithEntry, OccupiedMapEntry, VacantMapEntry},
};
use core::{
fmt::{self, Debug},
mem,
};
#[derive(Debug)]
pub struct OccupiedEntry<'a, N, NI, EI, NM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
NM: MapWithEntry<Node<N, EI>, Key = NI> + 'a,
{
pub(super) entry: NM::OccupiedEntry<'a>,
}
impl<'a, N, NI, EI, NM> OccupiedEntry<'a, N, NI, EI, NM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
NM: MapWithEntry<Node<N, EI>, Key = NI> + 'a,
{
pub fn get(&self) -> &N {
&self.entry.get().weight
}
pub fn get_mut(&mut self) -> &mut N {
&mut self.entry.get_mut().weight
}
pub fn into_mut(self) -> &'a mut N {
&mut self.entry.into_mut().weight
}
pub fn replace(&mut self, value: N) -> N {
mem::replace(&mut self.entry.get_mut().weight, value)
}
pub fn remove(self) -> Result<N, RemoveNodeError> {
let node = self.entry.get();
if node.next_outgoing_edge.is_none() && node.next_incoming_edge.is_none() {
Ok(self.entry.remove().weight)
} else {
Err(RemoveNodeError)
}
}
}
#[derive(Debug)]
pub struct VacantEntry<'a, N, NI, EI, NM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
NM: MapWithEntry<Node<N, EI>, Key = NI> + 'a,
{
pub(super) entry: NM::VacantEntry<'a>,
}
impl<'a, N, NI, EI, NM> VacantEntry<'a, N, NI, EI, NM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
NM: MapWithEntry<Node<N, EI>, Key = NI> + 'a,
{
pub fn insert<'l>(self, weight: N) -> &'l mut N
where
Self: 'l,
{
&mut self
.entry
.insert(Node {
weight,
next_incoming_edge: None,
next_outgoing_edge: None,
})
.weight
}
}
pub enum Entry<'a, N, NI, EI, NM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
NM: MapWithEntry<Node<N, EI>, Key = NI>,
{
Occupied(OccupiedEntry<'a, N, NI, EI, NM>),
Vacant(VacantEntry<'a, N, NI, EI, NM>),
}
impl<'a, N, NI, EI, NM> Entry<'a, N, NI, EI, NM>
where
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
NM: MapWithEntry<Node<N, EI>, Key = NI>,
{
pub fn or_insert(self, default: N) -> &'a mut N {
match self {
Entry::Vacant(entry) => entry.insert(default),
Entry::Occupied(entry) => entry.into_mut(),
}
}
pub fn or_insert_with<F: FnOnce() -> N>(self, f: F) -> &'a mut N {
match self {
Entry::Vacant(entry) => entry.insert(f()),
Entry::Occupied(entry) => entry.into_mut(),
}
}
}
impl<'a, N, NI, EI, NM> Debug for Entry<'a, N, NI, EI, NM>
where
N: Debug,
NI: Copy + Eq + Debug + 'static,
EI: Copy + Eq + Debug + 'static,
NM: MapWithEntry<Node<N, EI>, Key = NI> + Debug,
NM::VacantEntry<'a>: Debug,
NM::OccupiedEntry<'a>: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Entry::Vacant(entry) => f.debug_tuple("Entry::Vacant").field(entry).finish(),
Entry::Occupied(entry) => f.debug_tuple("Entry::Occupied").field(entry).finish(),
}
}
}