blob: 2dd00338b319b5f153d4cda8c98c49d431218ad9 [file] [log] [blame]
use crate::{edge::EdgeMut, graph::Graph, node::NodeMut, storage::RetainableGraphStorage};
impl<S> Graph<S>
where
S: RetainableGraphStorage,
{
/// Retains only the nodes and edges specified by the predicate.
///
/// For every node and edge in the graph, the predicate is called with a mutable reference to
/// the node or edge,
/// if the predicate returns `false` then the node or edge is removed from the graph.
///
/// The order in which the different functions are called is not guaranteed and may differ
/// between implementations.
///
/// Should a node be connected, all edges connected to that node will be removed as well, an
/// implementation may decide to omit these when calling the `edges` closures, or call the
/// closure for them as well, but ignore the result.
///
/// # Example
///
/// ```
/// use std::{collections::HashSet, iter::once};
///
/// use petgraph_dino::DiDinoGraph;
///
/// let mut graph = DiDinoGraph::new();
///
/// let a = *graph.insert_node(1).id();
/// let b = *graph.insert_node(2).id();
/// let c = *graph.insert_node(3).id();
///
/// let ab = *graph.insert_edge(4, &a, &b).id();
/// let bc = *graph.insert_edge(5, &b, &c).id();
/// let ca = *graph.insert_edge(6, &c, &a).id();
///
/// graph.retain(|node| node.weight() % 2 == 1, |edge| edge.weight() % 2 == 0);
///
/// assert_eq!(
/// graph
/// .nodes()
/// .map(|node| (*node.id(), *node.weight()))
/// .collect::<HashSet<_>>(),
/// [(a, 1), (c, 3)].into_iter().collect::<HashSet<_>>()
/// );
///
/// assert_eq!(
/// graph
/// .edges()
/// .map(|edge| (*edge.id(), *edge.weight()))
/// .collect::<HashSet<_>>(),
/// // as you can see here, although `ab` would've been retained, `b` was removed, so
/// // the edge was removed as well.
/// once((ca, 6)).collect::<HashSet<_>>()
/// );
/// ```
pub fn retain(
&mut self,
nodes: impl FnMut(NodeMut<'_, S>) -> bool,
edges: impl FnMut(EdgeMut<'_, S>) -> bool,
) {
self.storage.retain(nodes, edges);
}
/// Retains only the nodes specified by the predicate.
///
/// If you are going to retain edges as well, it is more efficient to use [`Self::retain`].
///
/// For every node in the graph, the predicate is invoked, if the predicate
/// evaluates to true the node is retained, otherwise the node and all connected edges are
/// removed.
///
/// # Example
///
/// ```
/// use std::{collections::HashSet, iter::once};
///
/// use petgraph_dino::DiDinoGraph;
///
/// let mut graph = DiDinoGraph::new();
///
/// let a = *graph.insert_node(1).id();
/// let b = *graph.insert_node(2).id();
/// let c = *graph.insert_node(3).id();
///
/// let ab = *graph.insert_edge(4, &a, &b).id();
/// let bc = *graph.insert_edge(5, &b, &c).id();
/// let ca = *graph.insert_edge(6, &c, &a).id();
///
/// graph.retain_nodes(|node| node.weight() % 2 == 1);
///
/// assert_eq!(
/// graph
/// .nodes()
/// .map(|node| (*node.id(), *node.weight()))
/// .collect::<HashSet<_>>(),
/// [(a, 1), (c, 3)].into_iter().collect::<HashSet<_>>()
/// );
///
/// assert_eq!(
/// graph
/// .edges()
/// .map(|edge| (*edge.id(), *edge.weight()))
/// .collect::<HashSet<_>>(),
/// // `ab` and `bc` were removed, because the `b` node wasn't retained.
/// once((ca, 6)).collect::<HashSet<_>>()
/// );
/// ```
pub fn retain_nodes(&mut self, f: impl FnMut(NodeMut<'_, S>) -> bool) {
self.storage.retain_nodes(f);
}
/// Retains only the edges specified by the predicate.
///
/// If you are going to retain nodes based on a predicate as well, it is more efficient to
/// instead use [`Self::retain`].
///
/// For every edge in the graph, the predicate is invoked, if the predicate
/// evaluates to true the edge is retained, otherwise the edge is removed.
///
/// # Example
///
/// ```
/// use std::{collections::HashSet, iter::once};
///
/// use petgraph_dino::DiDinoGraph;
///
/// let mut graph = DiDinoGraph::new();
///
/// let a = *graph.insert_node(1).id();
/// let b = *graph.insert_node(2).id();
/// let c = *graph.insert_node(3).id();
///
/// let ab = *graph.insert_edge(4, &a, &b).id();
/// let bc = *graph.insert_edge(5, &b, &c).id();
/// let ca = *graph.insert_edge(6, &c, &a).id();
///
/// graph.retain_edges(|edge| edge.weight() % 2 == 0);
///
/// assert_eq!(
/// graph
/// .nodes()
/// .map(|node| (*node.id(), *node.weight()))
/// .collect::<HashSet<_>>(),
/// [(a, 1), (b, 2), (c, 3)].into_iter().collect::<HashSet<_>>()
/// );
///
/// assert_eq!(
/// graph
/// .edges()
/// .map(|edge| (*edge.id(), *edge.weight()))
/// .collect::<HashSet<_>>(),
/// [(ab, 4), (ca, 6)].into_iter().collect::<HashSet<_>>()
/// );
/// ```
pub fn retain_edges(&mut self, f: impl FnMut(EdgeMut<'_, S>) -> bool) {
self.storage.retain_edges(f);
}
}