use core::ops::Neg;
use crate::UUID;
impl Neg for UUID {
type Output = Self;
#[inline]
fn neg(self) -> Self::Output {
Self::from_u128(self.to_u128().wrapping_neg())
}
}
impl Neg for &UUID {
type Output = UUID;
#[inline]
fn neg(self) -> Self::Output {
UUID::from_u128(self.to_u128().wrapping_neg())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn neg_zero() {
assert_eq!(-UUID::nil(), UUID::nil());
}
#[test]
fn neg_one() {
let one = UUID::from(1u128);
assert_eq!(-one, UUID::max());
}
#[test]
fn neg_max() {
assert_eq!(-UUID::max(), UUID::from(1u128));
}
#[test]
fn neg_two() {
let two = UUID::from(2u128);
assert_eq!(u128::from(-two), u128::MAX - 1);
}
#[test]
fn neg_ref_uuid() {
let uuid = UUID::from(1u128);
assert_eq!(-&uuid, UUID::max());
}
#[test]
fn additive_inverse() {
let values = [0u128, 1, 42, 12345, u128::MAX / 2, u128::MAX];
for v in values {
let uuid = UUID::from(v);
assert_eq!(
uuid + (-uuid),
UUID::nil(),
"additive inverse failed for {v}"
);
}
}
#[test]
fn double_negation_is_identity() {
let values = [0u128, 1, 42, 12345, u128::MAX / 2, u128::MAX];
for v in values {
let uuid = UUID::from(v);
assert_eq!(-(-uuid), uuid, "double negation failed for {v}");
}
}
#[test]
fn negation_is_equivalent_to_not_plus_one() {
let values = [0u128, 1, 42, 12345, u128::MAX / 2, u128::MAX];
for v in values {
let uuid = UUID::from(v);
let negated = -uuid;
let not_plus_one = !uuid + 1u32;
assert_eq!(negated, not_plus_one, "neg != !x+1 for {v}");
}
}
#[test]
fn subtraction_via_negation() {
let a = UUID::from(100u128);
let b = UUID::from(30u128);
assert_eq!(a - b, a + (-b));
}
#[test]
fn twos_complement_minus_one() {
let minus_one = -UUID::from(1u128);
assert_eq!(minus_one, UUID::max());
assert!(minus_one.as_bytes().iter().all(|&b| b == 0xFF));
}
#[test]
fn twos_complement_minus_two() {
let minus_two = -UUID::from(2u128);
assert_eq!(u128::from(minus_two), u128::MAX - 1);
let bytes = minus_two.as_bytes();
assert!(bytes[..15].iter().all(|&b| b == 0xFF));
assert_eq!(bytes[15], 0xFE);
}
#[test]
fn twos_complement_high_bit() {
let high_bit = UUID::from(1u128 << 127);
assert_eq!(-high_bit, high_bit);
}
#[test]
fn neg_various_patterns() {
let patterns = [
0b1010_1010u128,
0b1111_0000u128,
0x0123_4567_89ab_cdef_u128,
(1u128 << 64) - 1, 1u128 << 64, ];
for v in patterns {
let uuid = UUID::from(v);
assert_eq!(
uuid + (-uuid),
UUID::nil(),
"additive inverse failed for {v:#x}"
);
assert_eq!(-(-uuid), uuid, "double negation failed for {v:#x}");
}
}
#[test]
fn neg_consecutive_values() {
for v in 0u128..100 {
let neg_v = -UUID::from(v);
let neg_v_plus_1 = -UUID::from(v + 1);
assert_eq!(neg_v - 1u32, neg_v_plus_1);
}
}
}