use core::num::NonZeroU32;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[non_exhaustive]
pub struct SymbolStackVariable(NonZeroU32);
impl SymbolStackVariable {
pub const INITIAL: Self = Self(NonZeroU32::MIN);
#[must_use]
pub fn new(id: u32) -> Option<Self> {
NonZeroU32::new(id).map(Self)
}
#[must_use]
pub const fn get(self) -> u32 {
self.0.get()
}
#[must_use]
pub fn with_offset(self, offset: u32) -> Option<Self> {
self.0.checked_add(offset).map(Self)
}
}
#[cfg(test)]
mod tests {
use super::SymbolStackVariable;
#[test]
fn zero_numbers_no_variable() {
assert_eq!(SymbolStackVariable::new(0), None);
}
#[test]
fn the_initial_variable_is_number_one() {
assert_eq!(SymbolStackVariable::INITIAL.get(), 1);
}
#[test]
fn an_offset_renumbers_a_variable_up() {
assert_eq!(
SymbolStackVariable::INITIAL.with_offset(2),
SymbolStackVariable::new(3)
);
}
#[test]
fn an_offset_past_the_last_number_gives_no_variable() {
let last = SymbolStackVariable::new(u32::MAX).unwrap();
assert_eq!(last.with_offset(1), None);
assert_eq!(last.with_offset(0), Some(last));
}
}