fluidattacks-blends-domain 0.41.0

Blends functional core: pure AST graph to syntax graph (no_std)
Documentation
use core::num::NonZeroU32;

/// Stands for the unknown rest of a partial symbol stack.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
#[non_exhaustive]
pub struct SymbolStackVariable(NonZeroU32);

impl SymbolStackVariable {
    /// The first variable of a path.
    pub const INITIAL: Self = Self(NonZeroU32::MIN);

    /// The variable numbered `id`; `None` for 0, which numbers no variable.
    #[must_use]
    pub fn new(id: u32) -> Option<Self> {
        NonZeroU32::new(id).map(Self)
    }

    /// This variable's number.
    #[must_use]
    pub const fn get(self) -> u32 {
        self.0.get()
    }

    /// This variable renumbered `offset` places up; `None` past the last number.
    #[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));
    }
}