mapgraph 0.12.0

A directed graph that can also be used as an arbitrary map.
Documentation
use crate::{
    graph::{iter, Edge},
    IntKeyMap, MapWithCapacity,
};
use core::{
    fmt::Debug,
    marker::PhantomData,
    ops::{Index, IndexMut},
};
#[cfg(feature = "rayon")]
use {
    crate::map::ParIterMap,
    crate::util::{ParEdgeWeightIter, ParEdgeWeightIterMut},
    rayon::iter::ParallelIterator,
};

/// A wrapper for edge maps that disallows structural changes to the graph.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)]
pub struct Edges<E, NI, EI, EM>
where
    NI: Copy + Eq + Debug + 'static,
    EI: Copy + Eq + Debug + 'static,
    EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
    pub(super) map: EM,
    #[cfg_attr(feature = "serde", serde(skip_serializing, default))]
    _marker: PhantomData<(E, NI, EI, EM)>,
}

impl<E, NI, EI, EM> Edges<E, NI, EI, EM>
where
    NI: Copy + Eq + Debug + 'static,
    EI: Copy + Eq + Debug + 'static,
    EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
    /// Returns true if the edge map contains the provided index.
    pub fn contains_key(&self, index: EI) -> bool {
        self.map.contains_key(index)
    }

    /// Returns an immutable reference to an edge if the index is present in the node map.
    pub fn get(&self, index: EI) -> Option<&Edge<E, NI, EI>> {
        self.map.get(index)
    }

    /// Returns a mutable reference to an edge if the index is present in the node map.
    pub fn get_mut(&mut self, index: EI) -> Option<&mut Edge<E, NI, EI>> {
        self.map.get_mut(index)
    }

    /// Returns an immutable reference to an edge's weight if the index is present in the edge map.
    pub fn weight(&self, index: EI) -> Option<&E> {
        self.map.get(index).map(Edge::weight)
    }

    /// Returns a mutable reference to an edge's weight if the index is present in the edge map.
    pub fn weight_mut(&mut self, index: EI) -> Option<&mut E> {
        self.map.get_mut(index).map(Edge::weight_mut)
    }

    /// Returns an immutable iterator over the edges in the edge map.
    pub fn iter(&self) -> EM::Iter<'_> {
        self.map.iter()
    }

    /// Returns a mutable iterator over the edges in the edge map.
    pub fn iter_mut(&mut self) -> EM::IterMut<'_> {
        self.map.iter_mut()
    }

    /// Returns an immutable iterator over the weights of edges stored in the edge map.
    pub fn iter_weights(&self) -> iter::EdgeWeights<'_, E, NI, EI, EM> {
        iter::EdgeWeights { inner: self.iter() }
    }

    /// Returns a mutable iterator over the weights of edges stored in the edge map.
    pub fn iter_weights_mut(&mut self) -> iter::EdgeWeightsMut<'_, E, NI, EI, EM> {
        iter::EdgeWeightsMut {
            inner: self.iter_mut(),
        }
    }

    /// Returns the amount of edges stored in the edge map.
    pub fn len(&self) -> usize {
        self.map.len()
    }

    /// Returns a boolean indicating whether the edge map contains no edges.
    pub fn is_empty(&self) -> bool {
        self.map.is_empty()
    }
}

impl<E, NI, EI, EM> Edges<E, NI, EI, EM>
where
    NI: Copy + Eq + Debug + 'static,
    EI: Copy + Eq + Debug + 'static,
    EM: IntKeyMap<Edge<E, NI, EI>, Key = EI> + MapWithCapacity<Edge<E, NI, EI>, Key = EI>,
{
    pub(super) fn with_capacity(capacity: usize) -> Self {
        Self {
            map: EM::with_capacity(capacity),
            _marker: PhantomData,
        }
    }
}

#[cfg(feature = "rayon")]
impl<E, NI, EI, EM> Edges<E, NI, EI, EM>
where
    E: Sync + Send,
    NI: Copy + Eq + Debug + 'static,
    EI: Copy + Eq + Send + Sync + Debug + 'static,
    EM: IntKeyMap<Edge<E, NI, EI>, Key = EI> + ParIterMap<Edge<E, NI, EI>, Key = EI>,
{
    /// Returns an immutable parallel iterator over the nodes in the node map.
    pub fn par_iter(&self) -> EM::ParIter<'_> {
        self.map.par_iter()
    }

    /// Returns a mutable iterator over the nodes in the node map.
    pub fn par_iter_mut(&mut self) -> EM::ParIterMut<'_> {
        self.map.par_iter_mut()
    }

    /// Returns an immutable iterator over the weights of nodes stored in the node map.
    pub fn par_iter_weights(&self) -> ParEdgeWeightIter<EM::ParIter<'_>, NI, EI, E> {
        self.map
            .par_iter()
            .map(|(index, node)| (index, node.weight()))
    }

    /// Returns a mutable iterator over the weights of nodes stored in the node map.
    pub fn par_iter_weights_mut(&mut self) -> ParEdgeWeightIterMut<EM::ParIterMut<'_>, NI, EI, E> {
        self.map
            .par_iter_mut()
            .map(|(index, node)| (index, node.weight_mut()))
    }
}

impl<E, NI, EI, EM> Default for Edges<E, NI, EI, EM>
where
    NI: Copy + Eq + Debug + 'static,
    EI: Copy + Eq + Debug + 'static,
    EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
    fn default() -> Self {
        Self {
            map: Default::default(),
            _marker: PhantomData,
        }
    }
}

impl<E, NI, EI, EM> Index<EI> for Edges<E, NI, EI, EM>
where
    NI: Copy + Eq + Debug + 'static,
    EI: Copy + Eq + Debug + 'static,
    EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
    type Output = Edge<E, NI, EI>;

    fn index(&self, index: EI) -> &Self::Output {
        self.map.get(index).expect("invalid edge index")
    }
}

impl<E, NI, EI, EM> IndexMut<EI> for Edges<E, NI, EI, EM>
where
    NI: Copy + Eq + Debug + 'static,
    EI: Copy + Eq + Debug + 'static,
    EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
    fn index_mut(&mut self, index: EI) -> &mut Self::Output {
        self.map.get_mut(index).expect("invalid edge index")
    }
}

impl<'a, E, NI, EI, EM> IntoIterator for &'a Edges<E, NI, EI, EM>
where
    NI: Copy + Eq + Debug + 'static,
    EI: Copy + Eq + Debug + 'static,
    EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
    type Item = (EI, &'a Edge<E, NI, EI>);
    type IntoIter = EM::Iter<'a>;

    fn into_iter(self) -> Self::IntoIter {
        self.map.iter()
    }
}

impl<'a, E, NI, EI, EM> IntoIterator for &'a mut Edges<E, NI, EI, EM>
where
    NI: Copy + Eq + Debug + 'static,
    EI: Copy + Eq + Debug + 'static,
    EM: IntKeyMap<Edge<E, NI, EI>, Key = EI>,
{
    type Item = (EI, &'a mut Edge<E, NI, EI>);
    type IntoIter = EM::IterMut<'a>;

    fn into_iter(self) -> Self::IntoIter {
        self.map.iter_mut()
    }
}