From 97591f52ba6022e2d2bef4c50dfc66065209c47f Mon Sep 17 00:00:00 2001 From: Bas Dirks Date: Fri, 5 Apr 2024 07:41:12 +0200 Subject: [PATCH] test: add doctests - Add doctest for `ops::indegree::Indegree`. - Add doctest for `ops::is_edge::IsEdge`. - Add doctest for `ops::iter_all_edges::IterAllEdges`. - Add doctest for `ops::iter_all_weighted_edges::IterAllWeightedEdges`. - Add doctest for `ops::iter_edges::IterEdges`. - Add doctest for `ops::iter_weighted_edges::IterWeightedEdges`. - Add doctest for `ops::iter_vertices::IterVertices`. - Add doctest for `ops::outdegree::OutDegree`. - Add doctest for `ops::remove_edge::RemoveEdge`. - Add documentation for `ops::indegree`. - Add documentation for `ops::is_edge`. - Add documentation for `ops::iter_all_edges`. - Add documentation for `ops::iter_all_weighted_edges`. - Add documentation for `ops::iter_edges`. - Add documentation for `ops::iter_vertices`. - Add documentation for `ops::iter_weighted_edges`. - Add documentation for `ops::outdegree`. - Add documentation for `ops::remove_edge`. --- CHANGELOG.md | 39 ++++++-- src/ops/add_edge.rs | 34 ++++--- src/ops/add_weighted_edge.rs | 36 +++---- src/ops/indegree.rs | 34 +++++++ src/ops/is_edge.rs | 118 ++++++++++++++++++++++ src/ops/iter_all_edges.rs | 30 ++++++ src/ops/iter_all_weighted_edges.rs | 30 ++++++ src/ops/iter_edges.rs | 62 ++++++++++++ src/ops/iter_vertices.rs | 32 ++++++ src/ops/iter_weighted_edges.rs | 68 +++++++++++++ src/ops/mod.rs | 14 --- src/ops/outdegree.rs | 26 +++++ src/ops/remove_edge.rs | 153 +++++++++++++++++++++++++++++ 13 files changed, 621 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e87186a..c901896 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,16 +7,21 @@ - Add `dfs::*`. - Add `dijkstra::mssp`. - Add `dijkstra::sssp`. +- Add implementation documentation for `AddEdge`. +- Add implementation documentation for `AddWeightedEdge`. +- Add implementation documentation for `CountAllEdges`. +- Add implementation documentation for `CountAllVertices`. +- Add implementation documentation for `EdgeWeight`. +- Add implementation documentation for `Indegree`. +- Add implementation documentation for `IsEdge`. +- Add implementation documentation for `IterAllEdges`. +- Add implementation documentation for `IterAllWeightedEdges`. +- Add implementation documentation for `IterEdges`. +- Add implementation documentation for `IterWeightedEdges`. +- Add implementation documentation for `Outdegree`. +- Add implementation documentation for `RemoveEdge`. - Add doctest for `AdjacencyMatrix::new`. - Add doctest for `AdjacencyMatrix::toggle`. -- Add doctest for `Indegree`. -- Add doctest for `IsEdge`. -- Add doctest for `IterAllEdges`. -- Add doctest for `IterAllWeightedEdges`. -- Add doctest for `IterEdges`. -- Add doctest for `IterWeightedEdges`. -- Add doctest for `Outdegree`. -- Add doctest for `RemoveEdge`. ## [0.5.3] - Unreleased @@ -26,10 +31,28 @@ - Add doctest for `ops::count_all_edges::CountAllEdges`. - Add doctest for `ops::count_all_vertices::CountAllVertices`. - Add doctest for `ops::edge_weight::EdgeWeight`. +- Add doctest for `ops::indegree::Indegree`. +- Add doctest for `ops::is_edge::IsEdge`. +- Add doctest for `ops::iter_all_edges::IterAllEdges`. +- Add doctest for `ops::iter_all_weighted_edges::IterAllWeightedEdges`. +- Add doctest for `ops::iter_edges::IterEdges`. +- Add doctest for `ops::iter_weighted_edges::IterWeightedEdges`. +- Add doctest for `ops::iter_vertices::IterVertices`. +- Add doctest for `ops::outdegree::OutDegree`. +- Add doctest for `ops::remove_edge::RemoveEdge`. - Add documentation for `ops::add_weighted_edge`. - Add documentation for `ops::count_all_edges`. - Add documentation for `ops::count_all_vertices`. - Add documentation for `ops::edge_weight`. +- Add documentation for `ops::indegree`. +- Add documentation for `ops::is_edge`. +- Add documentation for `ops::iter_all_edges`. +- Add documentation for `ops::iter_all_weighted_edges`. +- Add documentation for `ops::iter_edges`. +- Add documentation for `ops::iter_vertices`. +- Add documentation for `ops::iter_weighted_edges`. +- Add documentation for `ops::outdegree`. +- Add documentation for `ops::remove_edge`. ## [0.5.2] - 2024-04-04 diff --git a/src/ops/add_edge.rs b/src/ops/add_edge.rs index 51a824f..606c2d6 100644 --- a/src/ops/add_edge.rs +++ b/src/ops/add_edge.rs @@ -24,7 +24,23 @@ use { /// A trait to add an edge to an unweighted graph /// -/// # `AddEdge` and [`crate::ops::RemoveEdge`] +/// # Examples +/// +/// ``` +/// use graaf::ops::AddEdge; +/// +/// let mut graph = vec![Vec::new(); 3]; +/// +/// graph.add_edge(0, 1); +/// graph.add_edge(0, 2); +/// graph.add_edge(2, 0); +/// +/// assert_eq!(graph, vec![vec![1, 2], Vec::new(), vec![0]]); +/// ``` +/// +/// # Properties +/// +/// ## `AddEdge` and [`crate::ops::RemoveEdge`] /// /// Types that also implement [`crate::ops::RemoveEdge`] should ensure that the /// following property holds for every `graph`, `s`, and `t` of the given types: @@ -48,7 +64,7 @@ use { /// } /// ``` /// -/// # `AddEdge` and [`crate::ops::IsEdge`] +/// ## `AddEdge` and [`crate::ops::IsEdge`] /// /// Types that also implement [`crate::ops::IsEdge`] should ensure that the /// following property holds for every `graph`, `s`, and `t` of the given types: @@ -75,20 +91,6 @@ pub trait AddEdge { /// /// * `s`: The source vertex. /// * `t`: The target vertex. - /// - /// # Examples - /// - /// ``` - /// use graaf::ops::AddEdge; - /// - /// let mut graph = vec![Vec::new(); 3]; - /// - /// graph.add_edge(0, 1); - /// graph.add_edge(0, 2); - /// graph.add_edge(2, 0); - /// - /// assert_eq!(graph, vec![vec![1, 2], Vec::new(), vec![0]]); - /// ``` fn add_edge(&mut self, s: usize, t: usize); } diff --git a/src/ops/add_weighted_edge.rs b/src/ops/add_weighted_edge.rs index 569caa1..67b2e5e 100644 --- a/src/ops/add_weighted_edge.rs +++ b/src/ops/add_weighted_edge.rs @@ -27,7 +27,23 @@ use { /// A trait to add an edge to a weighted graph /// -/// # `AddWeightedEdge` and [`crate::ops::RemoveEdge`] +/// # Examples +/// +/// ``` +/// use graaf::ops::AddWeightedEdge; +/// +/// let mut graph: Vec> = vec![Vec::new(); 3]; +/// +/// graph.add_weighted_edge(0, 1, 2); +/// graph.add_weighted_edge(0, 2, 1); +/// graph.add_weighted_edge(1, 2, -3); +/// +/// assert_eq!(graph, vec![vec![(1, 2), (2, 1)], vec![(2, -3)], Vec::new()]); +/// ``` +/// +/// # Properties +/// +/// ## `AddWeightedEdge` and [`crate::ops::RemoveEdge`] /// /// Types that also implement [`crate::ops::RemoveEdge`] should ensure that the /// following property holds for every `graph`, `s`, `t`, and `w` of the given @@ -52,7 +68,7 @@ use { /// } /// ``` /// -/// # `AddWeightedEdge` and [`crate::ops::IsEdge`] +/// ## `AddWeightedEdge` and [`crate::ops::IsEdge`] /// /// Types that also implement [`crate::ops::IsEdge`] should ensure that the /// following property holds for every `graph`, `s`, `t`, and `w` of the given @@ -64,7 +80,7 @@ use { /// IsEdge, /// }; /// -/// fn prop_add_edge_is_edge(graph: &mut G, s: usize, t: usize, w: W) -> bool +/// fn prop_add_edge_weighted_is_edge(graph: &mut G, s: usize, t: usize, w: W) -> bool /// where /// G: AddWeightedEdge + IsEdge, /// { @@ -81,20 +97,6 @@ pub trait AddWeightedEdge { /// * `s`: The source vertex. /// * `t`: The target vertex. /// * `w`: The weight of the edge. - /// - /// # Examples - /// - /// ``` - /// use graaf::ops::AddWeightedEdge; - /// - /// let mut graph: Vec> = vec![Vec::new(); 3]; - /// - /// graph.add_weighted_edge(0, 1, 2); - /// graph.add_weighted_edge(0, 2, 1); - /// graph.add_weighted_edge(1, 2, -3); - /// - /// assert_eq!(graph, vec![vec![(1, 2), (2, 1)], vec![(2, -3)], Vec::new()]); - /// ``` fn add_weighted_edge(&mut self, s: usize, t: usize, w: W); } diff --git a/src/ops/indegree.rs b/src/ops/indegree.rs index c0eecb0..b7ac920 100644 --- a/src/ops/indegree.rs +++ b/src/ops/indegree.rs @@ -1,3 +1,21 @@ +//! A trait to get the indegree of a given vertex +//! +//! # Examples +//! +//! ``` +//! use { +//! graaf::ops::Indegree, +//! std::collections::HashSet, +//! }; +//! +//! let graph: Vec> = +//! vec![HashSet::from([1, 2]), HashSet::from([2]), HashSet::new()]; +//! +//! assert_eq!(graph.indegree(0), 0); +//! assert_eq!(graph.indegree(1), 1); +//! assert_eq!(graph.indegree(2), 2); +//! ``` + use { core::hash::BuildHasher, std::collections::{ @@ -7,6 +25,22 @@ use { }; /// A trait to get the indegree of a given vertex +/// +/// # Examples +/// +/// ``` +/// use { +/// graaf::ops::Indegree, +/// std::collections::HashSet, +/// }; +/// +/// let graph: Vec> = +/// vec![HashSet::from([1, 2]), HashSet::from([2]), HashSet::new()]; +/// +/// assert_eq!(graph.indegree(0), 0); +/// assert_eq!(graph.indegree(1), 1); +/// assert_eq!(graph.indegree(2), 2); +/// ``` pub trait Indegree { /// Returns the indegree of a vertex. /// diff --git a/src/ops/is_edge.rs b/src/ops/is_edge.rs index 489e6bf..14e011a 100644 --- a/src/ops/is_edge.rs +++ b/src/ops/is_edge.rs @@ -1,3 +1,30 @@ +//! A trait to check if an edge exists between two vertices +//! +//! # Examples +//! +//! ``` +//! use { +//! graaf::ops::IsEdge, +//! std::collections::HashSet, +//! }; +//! +//! let graph = vec![ +//! HashSet::from([1, 2]), +//! HashSet::from([0]), +//! HashSet::from([0, 1]), +//! ]; +//! +//! assert!(!graph.is_edge(0, 0)); +//! assert!(graph.is_edge(0, 1)); +//! assert!(graph.is_edge(0, 2)); +//! assert!(graph.is_edge(1, 0)); +//! assert!(!graph.is_edge(1, 1)); +//! assert!(!graph.is_edge(1, 2)); +//! assert!(graph.is_edge(2, 0)); +//! assert!(graph.is_edge(2, 1)); +//! assert!(!graph.is_edge(2, 2)); +//! ``` + use { core::hash::BuildHasher, std::collections::{ @@ -7,6 +34,97 @@ use { }; /// A trait to check if an edge exists between two vertices +/// +/// # Examples +/// +/// ``` +/// use { +/// graaf::ops::IsEdge, +/// std::collections::HashSet, +/// }; +/// +/// let graph = vec![ +/// HashSet::from([1, 2]), +/// HashSet::from([0]), +/// HashSet::from([0, 1]), +/// ]; +/// +/// assert!(!graph.is_edge(0, 0)); +/// assert!(graph.is_edge(0, 1)); +/// assert!(graph.is_edge(0, 2)); +/// assert!(graph.is_edge(1, 0)); +/// assert!(!graph.is_edge(1, 1)); +/// assert!(!graph.is_edge(1, 2)); +/// assert!(graph.is_edge(2, 0)); +/// assert!(graph.is_edge(2, 1)); +/// assert!(!graph.is_edge(2, 2)); +/// ``` +/// +/// # Properties +/// +/// ## `IsEdge` and [`crate::ops::AddEdge`] +/// +/// Types that also implement [`crate::ops::AddEdge`] should ensure that the +/// following property holds for every `graph`, `s`, and `t` of the given types: +/// +/// ``` +/// use graaf::ops::{ +/// AddEdge, +/// IsEdge, +/// }; +/// +/// fn prop_add_edge_is_edge(graph: &mut G, s: usize, t: usize) -> bool +/// where +/// G: AddEdge + IsEdge, +/// { +/// graph.add_edge(s, t); +/// +/// graph.is_edge(s, t) +/// } +/// ``` +/// +/// ## `IsEdge` and [`crate::ops::AddWeightedEdge`] +/// +/// Types that also implement [`crate::ops::AddWeightedEdge`] should ensure that +/// the following property holds for every `graph`, `s`, `t`, and `w` of the +/// given types: +/// +/// ``` +/// use graaf::ops::{ +/// AddWeightedEdge, +/// IsEdge, +/// }; +/// +/// fn prop_add_weighted_edge_is_edge(graph: &mut G, s: usize, t: usize, w: W) -> bool +/// where +/// G: AddWeightedEdge + IsEdge, +/// { +/// graph.add_weighted_edge(s, t, w); +/// +/// graph.is_edge(s, t) +/// } +/// ``` +/// +/// ## `IsEdge` and [`crate::ops::RemoveEdge`] +/// +/// Types that also implement [`crate::ops::RemoveEdge`] should ensure that the +/// following property holds for every `graph`, `s`, and `t` of the given types: +/// +/// ``` +/// use graaf::ops::{ +/// IsEdge, +/// RemoveEdge, +/// }; +/// +/// fn prop_remove_edge_is_edge(graph: &mut G, s: usize, t: usize) -> bool +/// where +/// G: IsEdge + RemoveEdge, +/// { +/// graph.remove_edge(s, t); +/// +/// !graph.is_edge(s, t) +/// } +/// ``` pub trait IsEdge { /// Checks if there is an edge from `s` to `t`. /// diff --git a/src/ops/iter_all_edges.rs b/src/ops/iter_all_edges.rs index f705f08..cbfc738 100644 --- a/src/ops/iter_all_edges.rs +++ b/src/ops/iter_all_edges.rs @@ -1,9 +1,39 @@ +//! A trait to iterate over all unweighted edges in a graph +//! +//! # Examples +//! +//! ``` +//! use graaf::ops::IterAllEdges; +//! +//! let graph = vec![(0, 1), (1, 2), (2, 0)]; +//! let mut iter = graph.iter_all_edges(); +//! +//! assert_eq!(iter.next(), Some(&(0, 1))); +//! assert_eq!(iter.next(), Some(&(1, 2))); +//! assert_eq!(iter.next(), Some(&(2, 0))); +//! assert_eq!(iter.next(), None); +//! ``` + use { core::hash::BuildHasher, std::collections::HashSet, }; /// A trait to iterate over all unweighted edges in a graph +/// +/// # Examples +/// +/// ``` +/// use graaf::ops::IterAllEdges; +/// +/// let graph = vec![(0, 1), (1, 2), (2, 0)]; +/// let mut iter = graph.iter_all_edges(); +/// +/// assert_eq!(iter.next(), Some(&(0, 1))); +/// assert_eq!(iter.next(), Some(&(1, 2))); +/// assert_eq!(iter.next(), Some(&(2, 0))); +/// assert_eq!(iter.next(), None); +/// ``` pub trait IterAllEdges { /// Returns an iterator that iterates over all edges in a graph. fn iter_all_edges(&self) -> impl Iterator; diff --git a/src/ops/iter_all_weighted_edges.rs b/src/ops/iter_all_weighted_edges.rs index 8f3e21b..6a056dc 100644 --- a/src/ops/iter_all_weighted_edges.rs +++ b/src/ops/iter_all_weighted_edges.rs @@ -1,9 +1,39 @@ +//! A trait to iterate over all weighted edges in a graph +//! +//! # Examples +//! +//! ``` +//! use graaf::ops::IterAllWeightedEdges; +//! +//! let graph = vec![(0, 1, 2), (1, 2, 3), (2, 0, 4)]; +//! let mut iter = graph.iter_all_weighted_edges(); +//! +//! assert_eq!(iter.next(), Some(&(0, 1, 2))); +//! assert_eq!(iter.next(), Some(&(1, 2, 3))); +//! assert_eq!(iter.next(), Some(&(2, 0, 4))); +//! assert_eq!(iter.next(), None); +//! ``` + use { core::hash::BuildHasher, std::collections::HashSet, }; /// A trait to iterate over all weighted edges in a graph +/// +/// # Examples +/// +/// ``` +/// use graaf::ops::IterAllWeightedEdges; +/// +/// let graph = vec![(0, 1, 2), (1, 2, 3), (2, 0, 4)]; +/// let mut iter = graph.iter_all_weighted_edges(); +/// +/// assert_eq!(iter.next(), Some(&(0, 1, 2))); +/// assert_eq!(iter.next(), Some(&(1, 2, 3))); +/// assert_eq!(iter.next(), Some(&(2, 0, 4))); +/// assert_eq!(iter.next(), None); +/// ``` pub trait IterAllWeightedEdges { /// Returns an iterator that iterates over all weighted edges in a graph. fn iter_all_weighted_edges<'a>(&'a self) -> impl Iterator diff --git a/src/ops/iter_edges.rs b/src/ops/iter_edges.rs index ec31ebc..c55794f 100644 --- a/src/ops/iter_edges.rs +++ b/src/ops/iter_edges.rs @@ -1,3 +1,65 @@ +//! A trait to iterate over all unweighted edges with a given source vertex +//! +//! # Examples +//! +//! ``` +//! use graaf::ops::IterEdges; +//! +//! let graph: [Vec; 4] = [vec![1, 2], vec![0, 2, 3], vec![0, 1, 3], vec![1, 2]]; +//! let mut iter = graph.iter_edges(0); +//! +//! assert_eq!(iter.next(), Some(1)); +//! assert_eq!(iter.next(), Some(2)); +//! assert_eq!(iter.next(), None); +//! +//! let mut iter = graph.iter_edges(1); +//! +//! assert_eq!(iter.next(), Some(0)); +//! assert_eq!(iter.next(), Some(2)); +//! assert_eq!(iter.next(), Some(3)); +//! assert_eq!(iter.next(), None); +//! +//! let mut iter = graph.iter_edges(2); +//! +//! assert_eq!(iter.next(), Some(0)); +//! assert_eq!(iter.next(), Some(1)); +//! assert_eq!(iter.next(), Some(3)); +//! assert_eq!(iter.next(), None); +//! +//! let mut iter = graph.iter_edges(3); +//! +//! assert_eq!(iter.next(), Some(1)); +//! assert_eq!(iter.next(), Some(2)); +//! assert_eq!(iter.next(), None); +//! ``` +//! +//! The order of the edges is not guaranteed for, e.g., `Vec>`: +//! +//! ``` +//! #![feature(assert_matches)] +//! +//! use { +//! graaf::ops::IterEdges, +//! std::{ +//! assert_matches::assert_matches, +//! collections::HashSet, +//! }, +//! }; +//! +//! let graph = vec![ +//! HashSet::from([1, 2]), +//! HashSet::from([0, 2, 3]), +//! HashSet::from([0, 1, 3]), +//! HashSet::from([1, 2]), +//! ]; +//! +//! let mut iter = graph.iter_edges(0); +//! +//! assert_matches!(iter.next(), Some(1 | 2)); +//! assert_matches!(iter.next(), Some(1 | 2)); +//! assert_eq!(iter.next(), None); +//! ``` + use { core::hash::BuildHasher, std::collections::{ diff --git a/src/ops/iter_vertices.rs b/src/ops/iter_vertices.rs index 936ef72..36d1db8 100644 --- a/src/ops/iter_vertices.rs +++ b/src/ops/iter_vertices.rs @@ -1,3 +1,20 @@ +//! A trait to iterate over all vertices in a graph +//! +//! # Example +//! +//! ``` +//! use graaf::ops::IterVertices; +//! +//! let graph: [Vec; 4] = [vec![1, 2], vec![0, 2, 3], vec![0, 1, 3], vec![1, 2]]; +//! let mut iter = graph.iter_vertices(); +//! +//! assert_eq!(iter.next(), Some(0)); +//! assert_eq!(iter.next(), Some(1)); +//! assert_eq!(iter.next(), Some(2)); +//! assert_eq!(iter.next(), Some(3)); +//! assert_eq!(iter.next(), None); +//! ``` + use { core::hash::BuildHasher, std::collections::{ @@ -7,6 +24,21 @@ use { }; /// A trait to iterate over all vertices in a graph +/// +/// # Example +/// +/// ``` +/// use graaf::ops::IterVertices; +/// +/// let graph: [Vec; 4] = [vec![1, 2], vec![0, 2, 3], vec![0, 1, 3], vec![1, 2]]; +/// let mut iter = graph.iter_vertices(); +/// +/// assert_eq!(iter.next(), Some(0)); +/// assert_eq!(iter.next(), Some(1)); +/// assert_eq!(iter.next(), Some(2)); +/// assert_eq!(iter.next(), Some(3)); +/// assert_eq!(iter.next(), None); +/// ``` pub trait IterVertices { /// Returns an iterator over the vertices. fn iter_vertices(&self) -> impl Iterator; diff --git a/src/ops/iter_weighted_edges.rs b/src/ops/iter_weighted_edges.rs index eecdfe4..21e0c19 100644 --- a/src/ops/iter_weighted_edges.rs +++ b/src/ops/iter_weighted_edges.rs @@ -1,3 +1,38 @@ +//! A trait to iterate over all weighted edges with a given source vertex +//! +//! # Examples +//! +//! ``` +//! use graaf::ops::IterWeightedEdges; +//! +//! let graph = vec![ +//! vec![(1, 2), (2, 3), (3, 4)], +//! vec![(2, 3), (3, 4), (4, 5)], +//! vec![(3, 4), (4, 5), (5, 6)], +//! ]; +//! +//! let mut iter = graph.iter_weighted_edges(0); +//! +//! assert_eq!(iter.next(), Some((1, 2))); +//! assert_eq!(iter.next(), Some((2, 3))); +//! assert_eq!(iter.next(), Some((3, 4))); +//! assert_eq!(iter.next(), None); +//! +//! let mut iter = graph.iter_weighted_edges(1); +//! +//! assert_eq!(iter.next(), Some((2, 3))); +//! assert_eq!(iter.next(), Some((3, 4))); +//! assert_eq!(iter.next(), Some((4, 5))); +//! assert_eq!(iter.next(), None); +//! +//! let mut iter = graph.iter_weighted_edges(2); +//! +//! assert_eq!(iter.next(), Some((3, 4))); +//! assert_eq!(iter.next(), Some((4, 5))); +//! assert_eq!(iter.next(), Some((5, 6))); +//! assert_eq!(iter.next(), None); +//! ``` + use { core::hash::BuildHasher, std::collections::{ @@ -7,6 +42,39 @@ use { }; /// A trait to iterate over all weighted edges with a given source vertex +/// +/// # Examples +/// +/// ``` +/// use graaf::ops::IterWeightedEdges; +/// +/// let graph = vec![ +/// vec![(1, 2), (2, 3), (3, 4)], +/// vec![(2, 3), (3, 4), (4, 5)], +/// vec![(3, 4), (4, 5), (5, 6)], +/// ]; +/// +/// let mut iter = graph.iter_weighted_edges(0); +/// +/// assert_eq!(iter.next(), Some((1, 2))); +/// assert_eq!(iter.next(), Some((2, 3))); +/// assert_eq!(iter.next(), Some((3, 4))); +/// assert_eq!(iter.next(), None); +/// +/// let mut iter = graph.iter_weighted_edges(1); +/// +/// assert_eq!(iter.next(), Some((2, 3))); +/// assert_eq!(iter.next(), Some((3, 4))); +/// assert_eq!(iter.next(), Some((4, 5))); +/// assert_eq!(iter.next(), None); +/// +/// let mut iter = graph.iter_weighted_edges(2); +/// +/// assert_eq!(iter.next(), Some((3, 4))); +/// assert_eq!(iter.next(), Some((4, 5))); +/// assert_eq!(iter.next(), Some((5, 6))); +/// assert_eq!(iter.next(), None); +/// ``` pub trait IterWeightedEdges { /// Returns an iterator over the edges of the vertex `s`. /// diff --git a/src/ops/mod.rs b/src/ops/mod.rs index cac60dd..c67f5c5 100644 --- a/src/ops/mod.rs +++ b/src/ops/mod.rs @@ -3,26 +3,12 @@ pub mod add_weighted_edge; pub mod count_all_edges; pub mod count_all_vertices; pub mod edge_weight; - -/// A trait to get the indegree of a given vertex pub mod indegree; - -/// A trait to check if an edge exists between two vertices pub mod is_edge; - -/// A trait to iterate over all unweighted edges in a graph pub mod iter_all_edges; - -/// A trait to iterate over all weighted edges in a graph pub mod iter_all_weighted_edges; - -/// A trait to iterate over all unweighted edges with a given source vertex pub mod iter_edges; - -/// A trait to iterate over all vertices in a graph pub mod iter_vertices; - -/// A trait to iterate over all weighted edges with a given source vertex pub mod iter_weighted_edges; /// A trait to get the outdegree of a given vertex diff --git a/src/ops/outdegree.rs b/src/ops/outdegree.rs index 465d096..1bf4015 100644 --- a/src/ops/outdegree.rs +++ b/src/ops/outdegree.rs @@ -1,3 +1,17 @@ +//! A trait to get the outdegree of a given vertex +//! +//! # Examples +//! +//! ``` +//! use graaf::ops::Outdegree; +//! +//! let graph = vec![vec![1, 2], vec![0], vec![1]]; +//! +//! assert_eq!(graph.outdegree(0), 2); +//! assert_eq!(graph.outdegree(1), 1); +//! assert_eq!(graph.outdegree(2), 1); +//! ``` + use { core::hash::BuildHasher, std::collections::{ @@ -7,6 +21,18 @@ use { }; /// A trait to get the outdegree of a given vertex +/// +/// # Examples +/// +/// ``` +/// use graaf::ops::Outdegree; +/// +/// let graph = vec![vec![1, 2], vec![0], vec![1]]; +/// +/// assert_eq!(graph.outdegree(0), 2); +/// assert_eq!(graph.outdegree(1), 1); +/// assert_eq!(graph.outdegree(2), 1); +/// ``` pub trait Outdegree { /// Returns the outdegree of a vertex. /// diff --git a/src/ops/remove_edge.rs b/src/ops/remove_edge.rs index 590f6de..df1c6b4 100644 --- a/src/ops/remove_edge.rs +++ b/src/ops/remove_edge.rs @@ -1,3 +1,45 @@ +//! A trait to remove an edge from a graph +//! +//! # Examples +//! +//! ``` +//! use { +//! graaf::ops::RemoveEdge, +//! std::collections::HashSet, +//! }; +//! +//! let mut graph = vec![ +//! HashSet::from([1, 2]), +//! HashSet::from([0]), +//! HashSet::from([1]), +//! ]; +//! +//! graph.remove_edge(0, 1); +//! +//! assert_eq!( +//! graph, +//! vec![HashSet::from([2]), HashSet::from([0]), HashSet::from([1])] +//! ); +//! +//! graph.remove_edge(0, 2); +//! +//! assert_eq!( +//! graph, +//! vec![HashSet::new(), HashSet::from([0]), HashSet::from([1])] +//! ); +//! +//! graph.remove_edge(1, 0); +//! +//! assert_eq!( +//! graph, +//! vec![HashSet::new(), HashSet::new(), HashSet::from([1])] +//! ); +//! +//! graph.remove_edge(2, 1); +//! +//! assert_eq!(graph, vec![HashSet::new(), HashSet::new(), HashSet::new()]); +//! ``` + use { core::hash::BuildHasher, std::collections::{ @@ -7,6 +49,117 @@ use { }; /// A trait to remove an edge from a graph +/// +/// # Examples +/// +/// ``` +/// use { +/// graaf::ops::RemoveEdge, +/// std::collections::HashSet, +/// }; +/// +/// let mut graph = vec![ +/// HashSet::from([1, 2]), +/// HashSet::from([0]), +/// HashSet::from([1]), +/// ]; +/// +/// graph.remove_edge(0, 1); +/// +/// assert_eq!( +/// graph, +/// vec![HashSet::from([2]), HashSet::from([0]), HashSet::from([1])] +/// ); +/// +/// graph.remove_edge(0, 2); +/// +/// assert_eq!( +/// graph, +/// vec![HashSet::new(), HashSet::from([0]), HashSet::from([1])] +/// ); +/// +/// graph.remove_edge(1, 0); +/// +/// assert_eq!( +/// graph, +/// vec![HashSet::new(), HashSet::new(), HashSet::from([1])] +/// ); +/// +/// graph.remove_edge(2, 1); +/// +/// assert_eq!(graph, vec![HashSet::new(), HashSet::new(), HashSet::new()]); +/// ``` +/// +/// # Properties +/// +/// ## `RemoveEdge` and [`crate::ops::AddEdge`] +/// +/// Types that also implement [`crate::ops::AddEdge`] should ensure that the +/// following property holds for every `graph`, `s`, and `t` of the given types: +/// +/// ``` +/// use graaf::ops::{ +/// AddEdge, +/// RemoveEdge, +/// }; +/// +/// fn prop_add_edge_remove_edge(graph: G, s: usize, t: usize) -> bool +/// where +/// G: AddEdge + Clone + PartialEq + RemoveEdge, +/// { +/// let mut clone = graph.clone(); +/// +/// clone.add_edge(s, t); +/// clone.remove_edge(s, t); +/// +/// graph == clone +/// } +/// ``` +/// +/// ## `RemoveEdge` and [`crate::ops::AddWeightedEdge`] +/// +/// Types that also implement [`crate::ops::AddWeightedEdge`] should ensure that +/// the following property holds for every `graph`, `s`, `t`, and `w` of the +/// +/// ``` +/// use graaf::ops::{ +/// AddWeightedEdge, +/// RemoveEdge, +/// }; +/// +/// fn prop_add_weighted_edge_remove_edge(graph: G, s: usize, t: usize, w: W) -> bool +/// where +/// G: AddWeightedEdge + Clone + PartialEq + RemoveEdge, +/// { +/// let mut clone = graph.clone(); +/// +/// clone.add_weighted_edge(s, t, w); +/// clone.remove_edge(s, t); +/// +/// graph == clone +/// } +/// ``` +/// +/// ## `RemoveEdge` and [`crate::ops::IsEdge`] +/// +/// Types that also implement [`crate::ops::IsEdge`] should ensure that the +/// following property holds for every `graph`, `s`, and `t` of the given types: +/// +/// ``` +/// use graaf::ops::{ +/// IsEdge, +/// RemoveEdge, +/// }; +/// +/// fn prop_remove_edge_is_edge(graph: &mut G, s: usize, t: usize) -> bool +/// where +/// G: IsEdge + RemoveEdge, +/// { +/// graph.remove_edge(s, t); +/// +/// !graph.is_edge(s, t) +/// } +/// ``` pub trait RemoveEdge { /// Remove the edge from `s` to `t`. ///