#![forbid(unsafe_code)]
use std::collections::HashSet;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NodeId(usize);
impl NodeId {
#[must_use]
pub const fn new(value: usize) -> Self {
Self(value)
}
#[must_use]
pub const fn value(&self) -> usize {
self.0
}
}
#[must_use]
pub fn node_ids(count: usize) -> Vec<NodeId> {
(0..count).map(NodeId::new).collect()
}
#[must_use]
pub fn contains_node(nodes: &[NodeId], node: NodeId) -> bool {
nodes.contains(&node)
}
#[must_use]
pub fn unique_nodes(nodes: &[NodeId]) -> Vec<NodeId> {
let mut seen = HashSet::with_capacity(nodes.len());
let mut unique = Vec::with_capacity(nodes.len());
for &node in nodes {
if seen.insert(node) {
unique.push(node);
}
}
unique
}
#[cfg(test)]
mod tests {
use super::{contains_node, node_ids, unique_nodes, NodeId};
#[test]
fn creates_node_ids() {
let nodes = node_ids(4);
assert_eq!(
nodes,
vec![
NodeId::new(0),
NodeId::new(1),
NodeId::new(2),
NodeId::new(3)
]
);
assert_eq!(NodeId::new(7).value(), 7);
}
#[test]
fn checks_containment() {
let nodes = [NodeId::new(1), NodeId::new(3)];
assert!(contains_node(&nodes, NodeId::new(3)));
assert!(!contains_node(&nodes, NodeId::new(2)));
}
#[test]
fn deduplicates_nodes_while_preserving_first_occurrence_order() {
let unique = unique_nodes(&[
NodeId::new(2),
NodeId::new(1),
NodeId::new(2),
NodeId::new(1),
NodeId::new(3),
]);
assert_eq!(unique, vec![NodeId::new(2), NodeId::new(1), NodeId::new(3)]);
}
}