uninum 0.1.1

A robust, ergonomic unified number type for Rust with automatic overflow handling, type promotion, and cross-type consistency.
Documentation
//! Bitwise OR Operation Tests
//!
//! This module contains comprehensive tests for bitwise OR operations on Number
//! types:
//!
//! - Basic OR operations
//! - OR with all ones (all ones result)
//! - OR with all zeros (identity)
//! - OR with self
//! - Error handling for non-integer types
//! - Mixed type OR operation failures
//!
//! These tests are only compiled when the `bitwise` feature is enabled.

use uninum::{Number, num};

#[test]
fn test_basic_or_operation() {
    // Test OR
    let c = Number::from(0b1010u64);
    let d = Number::from(0b1100u64);
    assert_eq!((c | d).unwrap(), Number::from(0b1110u64));
}

#[test]
fn test_try_bitor_method() {
    // Test try_bitor
    let a = Number::from(0b1010u64);
    let b = Number::from(0b1100u64);
    assert_eq!(a.try_bitor(&b), Some(Number::from(0b1110u64)));

    let float = num!(3.16);
    assert_eq!(float.try_bitor(&a), None);
}

#[test]
fn test_bitor_signed_integers() {
    let a = Number::from(-0b1010i64);
    let b = Number::from(-0b0101i64);
    assert_eq!((a | b).unwrap(), Number::from(-1i64));
}

#[test]
fn test_bitor_mismatched_types_error() {
    let signed = Number::from(-2i64);
    let unsigned = Number::from(3u64);
    assert!((signed | unsigned).is_err());
}

#[test]
fn test_small_integer_bitor() {
    let a = Number::from(0b1010u64);
    let b = Number::from(0b1100u64);

    assert_eq!(a.try_bitor(&b), Some(Number::from(0b1110u64)));
}

#[test]
fn test_large_integer_bitor() {
    let a = Number::from(0x1234567890ABCDEFu64);
    let b = Number::from(0xFEDCBA0987654321u64);

    assert!(a.try_bitor(&b).is_some());
}

#[test]
fn test_bitor_with_references() {
    let a = Number::from(0b1010u64);
    let b = Number::from(0b1100u64);

    // Test reference operations (using clones since bitwise ops don't support
    // references)
    assert_eq!((a.clone() | b.clone()).unwrap(), Number::from(0b1110u64));

    // Verify original values are still available
    assert_eq!(a, Number::from(0b1010u64));
    assert_eq!(b, Number::from(0b1100u64));
}

#[test]
fn test_bitor_patterns() {
    // Test common bit patterns
    let all_ones_u32 = Number::from(0xFFFFFFFFu64);
    let all_zeros_u32 = Number::from(0x00000000u64);
    let alternating_u32 = Number::from(0xAAAAAAAAu64); // 10101010...

    // OR with all ones = all ones
    assert_eq!(
        (alternating_u32.clone() | all_ones_u32.clone()).unwrap(),
        all_ones_u32
    );
    // OR with all zeros = identity
    assert_eq!(
        (alternating_u32.clone() | all_zeros_u32.clone()).unwrap(),
        alternating_u32
    );
}

#[test]
fn test_demorgan_or_part() {
    // Test De Morgan's laws: !(A & B) = !A | !B
    let a = Number::from(0xCC00CC00_u64);
    let b = Number::from(0xAA00AA00_u64);
    let not_a_and_b = (!(a.clone() & b.clone()).unwrap()).unwrap();
    let not_a_or_not_b = ((!a.clone()).unwrap() | (!b.clone()).unwrap()).unwrap();
    assert_eq!(not_a_and_b, not_a_or_not_b);
}

#[test]
#[cfg(feature = "decimal")]
fn test_bitor_with_decimal_fails() {
    use rust_decimal::Decimal;

    let dec = Number::from(Decimal::new(42, 0));
    let int = Number::from(42_u64);

    // All bitwise operations should fail for Decimal
    assert!((dec.clone() | int.clone()).is_err());

    // try_* methods should return None
    assert_eq!(dec.try_bitor(&int), None);
}