//! Non-zero check returning an `Option`.
use super::U512;

impl U512 {
    /// Returns `Some(self)` if the value is non-zero, or `None` if zero.
    ///
    /// Useful for early-return patterns with the `?` operator where zero
    /// inputs are invalid.
    ///
    /// # Examples
    ///
    /// ```
    /// use cnfy_uint::u512::U512;
    ///
    /// let v = U512::from_be_limbs([0, 0, 0, 0, 0, 0, 0, 42]);
    /// assert_eq!(v.non_zero(), Some(v));
    ///
    /// let z = U512::ZERO;
    /// assert_eq!(z.non_zero(), None);
    /// ```
    #[inline]
    pub const fn non_zero(self) -> Option<U512> {
        match self.const_eq(&U512::ZERO) {
            true => None,
            false => Some(self),
        }
    }
}

#[cfg(test)]
mod ai_tests {
    use super::*;

    /// Zero returns None.
    #[test]
    fn zero_is_none() {
        assert_eq!(U512::ZERO.non_zero(), None);
    }

    /// Non-zero returns Some.
    #[test]
    fn nonzero_is_some() {
        let v = U512::from_be_limbs([0, 0, 0, 0, 0, 0, 0, 1]);
        assert_eq!(v.non_zero(), Some(v));
    }

    /// Large value returns Some.
    #[test]
    fn large_value() {
        assert_eq!(U512::MAX.non_zero(), Some(U512::MAX));
    }

    /// MSB-only value returns Some.
    #[test]
    fn msb_only() {
        let v = U512::from_be_limbs([1, 0, 0, 0, 0, 0, 0, 0]);
        assert_eq!(v.non_zero(), Some(v));
    }
}
