//! Non-zero check returning an `Option`.

use super::U256;

impl U256 {
    /// 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 (e.g. modular inverse).
    ///
    /// # Examples
    ///
    /// ```
    /// use cnfy_uint::u256::U256;
    ///
    /// let v = U256::from_be_limbs([0, 0, 0, 42]);
    /// assert_eq!(v.non_zero(), Some(v));
    ///
    /// let z = U256::from_be_limbs([0, 0, 0, 0]);
    /// assert_eq!(z.non_zero(), None);
    /// ```
    #[inline]
    pub const fn non_zero(self) -> Option<U256> {
        match self.const_eq(&U256::ZERO) {
            true => None,
            false => Some(self),
        }
    }
}

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

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

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

    /// Large value returns Some.
    #[test]
    fn large_value() {
        let v = U256::from_be_limbs([u64::MAX, u64::MAX, u64::MAX, u64::MAX]);
        assert_eq!(v.non_zero(), Some(v));
    }
}
