//! Constant-time equality comparison for [`U384`].
use super::U384;

impl U384 {
    /// Compares two [`U384`] values for equality in a `const` context.
    ///
    /// This is needed because `PartialEq::eq` is not `const`. All six
    /// limbs are compared.
    ///
    /// # Examples
    ///
    /// ```
    /// use cnfy_uint::u384::U384;
    ///
    /// const A: U384 = U384::from_be_limbs([0, 0, 0, 0, 0, 42]);
    /// const B: U384 = U384::from_be_limbs([0, 0, 0, 0, 0, 42]);
    /// const EQ: bool = A.const_eq(&B);
    /// assert!(EQ);
    /// ```
    #[inline]
    pub const fn const_eq(&self, other: &U384) -> bool {
        self.0[0] == other.0[0]
            && self.0[1] == other.0[1]
            && self.0[2] == other.0[2]
            && self.0[3] == other.0[3]
            && self.0[4] == other.0[4]
            && self.0[5] == other.0[5]
    }
}

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

    /// Equal values compare as equal.
    #[test]
    fn equal() {
        let a = U384::from_be_limbs([1, 2, 3, 4, 5, 6]);
        let b = U384::from_be_limbs([1, 2, 3, 4, 5, 6]);
        assert!(a.const_eq(&b));
    }

    /// Differing values compare as not equal.
    #[test]
    fn not_equal() {
        let a = U384::from_be_limbs([1, 2, 3, 4, 5, 6]);
        let b = U384::from_be_limbs([1, 2, 3, 4, 5, 7]);
        assert!(!a.const_eq(&b));
    }

    /// Agrees with PartialEq.
    #[test]
    fn agrees_with_partial_eq() {
        let a = U384::from_be_limbs([0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56]);
        let b = a;
        assert_eq!(a.const_eq(&b), a == b);
    }

    /// Works in const context.
    #[test]
    fn const_context() {
        const A: U384 = U384::from_be_limbs([0, 0, 0, 0, 0, 1]);
        const B: U384 = U384::ONE;
        const EQ: bool = A.const_eq(&B);
        assert!(EQ);
    }
}
