use std::num::NonZeroUsize;
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[repr(transparent)]
pub struct ItemIndex(usize);
impl ItemIndex {
#[must_use]
pub const fn new(ix: usize) -> Self {
Self(ix)
}
#[must_use]
pub const fn get(self) -> usize {
self.0
}
#[must_use]
pub fn decrement(self) -> Self {
Self(self.0 - 1)
}
#[must_use]
pub fn increment(self) -> Self {
Self(self.0 + 1)
}
}
pub type NodeIndex = usize;
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[repr(transparent)]
pub struct InstIndex(NonZeroUsize);
impl InstIndex {
#[must_use]
pub const fn new(ix: usize) -> Self {
Self(if let Some(ix) = NonZeroUsize::new(ix) {
ix
} else {
panic!("node index must be positive")
})
}
#[must_use]
pub const unsafe fn new_unchecked(ix: usize) -> Self {
Self(NonZeroUsize::new_unchecked(ix))
}
#[must_use]
pub const fn get(self) -> usize {
self.0.get()
}
#[must_use]
pub const fn decrement(self) -> Option<Self> {
if let Some(ix) = NonZeroUsize::new(self.0.get() - 1) {
Some(Self(ix))
} else {
None
}
}
#[must_use]
pub const fn increment(self) -> Self {
Self(unsafe { NonZeroUsize::new_unchecked(self.0.get() + 1) })
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn index_get() {
assert_eq!(ItemIndex::new(0).get(), 0);
assert_eq!(ItemIndex::new(123).get(), 123);
assert_eq!(ItemIndex::new(456789).get(), 456789);
assert_eq!(InstIndex::new(1).get(), 1);
assert_eq!(InstIndex::new(65).get(), 65);
assert_eq!(InstIndex::new(87935).get(), 87935);
}
#[test]
#[should_panic]
fn out_of_bounds_node_index() {
let _ = InstIndex::new(0);
}
#[test]
fn index_decrement() {
assert_eq!(ItemIndex::new(1).decrement(), ItemIndex::new(0));
assert_eq!(ItemIndex::new(15).decrement(), ItemIndex::new(14));
assert!(InstIndex::new(1).decrement().is_none());
assert_eq!(InstIndex::new(2).decrement(), Some(InstIndex::new(1)));
assert_eq!(InstIndex::new(565).decrement(), Some(InstIndex::new(564)));
}
#[test]
fn index_increment() {
assert_eq!(ItemIndex::new(0).increment(), ItemIndex::new(1));
assert_eq!(ItemIndex::new(1).increment(), ItemIndex::new(2));
assert_eq!(ItemIndex::new(133).increment(), ItemIndex::new(134));
assert_eq!(InstIndex::new(1).increment(), InstIndex::new(2));
assert_eq!(InstIndex::new(2).increment(), InstIndex::new(3));
assert_eq!(InstIndex::new(234).increment(), InstIndex::new(235));
}
}