Skip to main content

use_node/
lib.rs

1#![forbid(unsafe_code)]
2//! Primitive node identifier helpers.
3//!
4//! The crate keeps node identifiers explicit and lightweight through a small
5//! `NodeId` wrapper around `usize`.
6//!
7//! # Examples
8//!
9//! ```rust
10//! use use_node::{NodeId, contains_node, node_ids, unique_nodes};
11//!
12//! let nodes = node_ids(3);
13//! let unique = unique_nodes(&[NodeId::new(2), NodeId::new(1), NodeId::new(2)]);
14//!
15//! assert!(contains_node(&nodes, NodeId::new(1)));
16//! assert_eq!(unique, vec![NodeId::new(2), NodeId::new(1)]);
17//! ```
18
19use std::collections::HashSet;
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
22pub struct NodeId(usize);
23
24impl NodeId {
25    #[must_use]
26    pub const fn new(value: usize) -> Self {
27        Self(value)
28    }
29
30    #[must_use]
31    pub const fn value(&self) -> usize {
32        self.0
33    }
34}
35
36#[must_use]
37pub fn node_ids(count: usize) -> Vec<NodeId> {
38    (0..count).map(NodeId::new).collect()
39}
40
41#[must_use]
42pub fn contains_node(nodes: &[NodeId], node: NodeId) -> bool {
43    nodes.contains(&node)
44}
45
46#[must_use]
47pub fn unique_nodes(nodes: &[NodeId]) -> Vec<NodeId> {
48    let mut seen = HashSet::with_capacity(nodes.len());
49    let mut unique = Vec::with_capacity(nodes.len());
50
51    for &node in nodes {
52        if seen.insert(node) {
53            unique.push(node);
54        }
55    }
56
57    unique
58}
59
60#[cfg(test)]
61mod tests {
62    use super::{contains_node, node_ids, unique_nodes, NodeId};
63
64    #[test]
65    fn creates_node_ids() {
66        let nodes = node_ids(4);
67
68        assert_eq!(
69            nodes,
70            vec![
71                NodeId::new(0),
72                NodeId::new(1),
73                NodeId::new(2),
74                NodeId::new(3)
75            ]
76        );
77        assert_eq!(NodeId::new(7).value(), 7);
78    }
79
80    #[test]
81    fn checks_containment() {
82        let nodes = [NodeId::new(1), NodeId::new(3)];
83
84        assert!(contains_node(&nodes, NodeId::new(3)));
85        assert!(!contains_node(&nodes, NodeId::new(2)));
86    }
87
88    #[test]
89    fn deduplicates_nodes_while_preserving_first_occurrence_order() {
90        let unique = unique_nodes(&[
91            NodeId::new(2),
92            NodeId::new(1),
93            NodeId::new(2),
94            NodeId::new(1),
95            NodeId::new(3),
96        ]);
97
98        assert_eq!(unique, vec![NodeId::new(2), NodeId::new(1), NodeId::new(3)]);
99    }
100}