grapes 0.3.0

Persistent graph data structures: Tree, Graph, Arena & more
Documentation
use crate::graph;
use crate::graph::{EdgeId, NodeId};
use crate::map_graph::{EdgeEntry, NodeEntry, NodeMut, NodeRef};
use imbl::HashMap;
use std::hash::Hash;

/// Mutable reference to an edge in a [MapGraph](super::MapGraph)
///
/// The library guarantees that this references a valid node
#[derive(Debug)]
pub struct EdgeMut<
    'a,
    NodeKey: Hash + Eq + Clone,
    NodeData: Clone,
    EdgeKey: Hash + Eq + Clone,
    EdgeData: Clone,
> {
    inner: graph::EdgeMut<'a, NodeEntry<NodeKey, NodeData>, EdgeEntry<EdgeKey, EdgeData>>,
    node_map: &'a mut HashMap<NodeKey, NodeId>,
    edge_map: &'a mut HashMap<EdgeKey, EdgeId>,
}

impl<
        'a,
        NodeKey: Hash + Eq + Clone,
        NodeData: Clone,
        EdgeKey: Hash + Eq + Clone,
        EdgeData: Clone,
    > EdgeMut<'a, NodeKey, NodeData, EdgeKey, EdgeData>
{
    pub(crate) fn new(
        inner: graph::EdgeMut<'a, NodeEntry<NodeKey, NodeData>, EdgeEntry<EdgeKey, EdgeData>>,
        node_map: &'a mut HashMap<NodeKey, NodeId>,
        edge_map: &'a mut HashMap<EdgeKey, EdgeId>,
    ) -> Self {
        Self {
            inner,
            node_map,
            edge_map,
        }
    }

    /// Reference to data associated with this edge
    ///
    /// (aka the edge weight)
    #[must_use]
    pub fn data(&self) -> &EdgeData {
        &self.inner.data().data
    }

    /// A mutable reference to data associated with this edge
    ///
    /// (aka the edge weight)
    #[must_use]
    pub fn data_mut(&mut self) -> &mut EdgeData {
        &mut self.inner.data_mut().data
    }

    /// The edge's identifier
    ///
    /// You can use this to later reference the edge in the graph (if it still exists)
    #[must_use]
    pub fn key(&self) -> &EdgeKey {
        &self.inner.data().key
    }

    /// Reference to the node from which the edge starts
    ///
    /// (aka the tail of the arc)
    #[must_use]
    pub fn get_from_node(&self) -> NodeRef<NodeKey, NodeData, EdgeKey, EdgeData> {
        NodeRef::new(self.inner.get_from_node())
    }

    /// Mutable reference to the Node from which the edge starts
    ///
    /// (aka the tail of the arc)
    #[must_use]
    pub fn get_from_node_mut(&mut self) -> NodeMut<NodeKey, NodeData, EdgeKey, EdgeData> {
        NodeMut::new(self.inner.get_from_node_mut(), self.node_map, self.edge_map)
    }

    /// Reference to the Node the edge points to
    ///
    /// (aka the head of the arc)
    #[must_use]
    pub fn get_to_node(&self) -> NodeRef<NodeKey, NodeData, EdgeKey, EdgeData> {
        NodeRef::new(self.inner.get_to_node())
    }

    /// Mutable reference to the Node the edge points to
    ///
    /// (aka the head of the arc)
    #[must_use]
    pub fn get_to_node_mut(&mut self) -> NodeMut<NodeKey, NodeData, EdgeKey, EdgeData> {
        NodeMut::new(self.inner.get_to_node_mut(), self.node_map, self.edge_map)
    }

    /// Remove this edge from the graph
    ///
    /// Returns the data of the removed edge
    ///
    /// Note: there may be other edges with the same source and target nodes
    #[allow(clippy::must_use_candidate)]
    pub fn remove(self) -> EdgeEntry<EdgeKey, EdgeData> {
        let removed = self.inner.remove();

        self.edge_map.remove(&removed.key);

        removed
    }
}