fluidattacks_blends_domain/stack/resolve/
variables.rs1use core::num::NonZeroU32;
2
3#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
5#[non_exhaustive]
6pub struct SymbolStackVariable(NonZeroU32);
7
8impl SymbolStackVariable {
9 pub const INITIAL: Self = Self(NonZeroU32::MIN);
11
12 #[must_use]
14 pub fn new(id: u32) -> Option<Self> {
15 NonZeroU32::new(id).map(Self)
16 }
17
18 #[must_use]
20 pub const fn get(self) -> u32 {
21 self.0.get()
22 }
23
24 #[must_use]
26 pub fn with_offset(self, offset: u32) -> Option<Self> {
27 self.0.checked_add(offset).map(Self)
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::SymbolStackVariable;
34
35 #[test]
36 fn zero_numbers_no_variable() {
37 assert_eq!(SymbolStackVariable::new(0), None);
38 }
39
40 #[test]
41 fn the_initial_variable_is_number_one() {
42 assert_eq!(SymbolStackVariable::INITIAL.get(), 1);
43 }
44
45 #[test]
46 fn an_offset_renumbers_a_variable_up() {
47 assert_eq!(
48 SymbolStackVariable::INITIAL.with_offset(2),
49 SymbolStackVariable::new(3)
50 );
51 }
52
53 #[test]
54 fn an_offset_past_the_last_number_gives_no_variable() {
55 let last = SymbolStackVariable::new(u32::MAX).unwrap();
56
57 assert_eq!(last.with_offset(1), None);
58 assert_eq!(last.with_offset(0), Some(last));
59 }
60}