#![warn(missing_docs)]
#![warn(clippy::all)]
#![warn(clippy::pedantic)]
#![warn(clippy::nursery)]
#![allow(clippy::module_name_repetitions)]
#[macro_use]
#[allow(unused_macros)]
mod generated_contracts;
pub mod benchmark;
pub mod chaos;
pub mod vec;
pub use benchmark::*;
pub use vec::{IntoIter, Iter, IterMut, TruenoVec};
#[must_use]
pub const fn add(left: u64, right: u64) -> u64 {
left + right
}
#[must_use]
pub const fn subtract(left: u64, right: u64) -> u64 {
left - right
}
#[must_use]
pub const fn multiply(left: u64, right: u64) -> u64 {
left * right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add_basic() {
assert_eq!(add(2, 2), 4);
assert_eq!(add(0, 0), 0);
assert_eq!(add(1, 1), 2);
}
#[test]
fn test_add_identity() {
assert_eq!(add(5, 0), 5);
assert_eq!(add(0, 5), 5);
}
#[test]
fn test_add_commutativity() {
assert_eq!(add(3, 7), add(7, 3));
assert_eq!(add(10, 20), add(20, 10));
}
#[test]
fn test_subtract_basic() {
assert_eq!(subtract(10, 5), 5);
assert_eq!(subtract(4, 2), 2);
}
#[test]
fn test_subtract_identity() {
assert_eq!(subtract(5, 0), 5);
assert_eq!(subtract(100, 0), 100);
}
#[test]
fn test_multiply_basic() {
assert_eq!(multiply(2, 3), 6);
assert_eq!(multiply(4, 5), 20);
}
#[test]
fn test_multiply_identity() {
assert_eq!(multiply(5, 1), 5);
assert_eq!(multiply(1, 5), 5);
}
#[test]
fn test_multiply_zero() {
assert_eq!(multiply(0, 5), 0);
assert_eq!(multiply(5, 0), 0);
assert_eq!(multiply(0, 0), 0);
}
#[test]
fn test_multiply_commutativity() {
assert_eq!(multiply(3, 7), multiply(7, 3));
assert_eq!(multiply(10, 20), multiply(20, 10));
}
}
#[cfg(test)]
mod property_tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn property_add_commutative(a in 0u64..1_000_000, b in 0u64..1_000_000) {
prop_assert_eq!(add(a, b), add(b, a));
}
}
proptest! {
#[test]
fn property_add_identity(a in 0u64..u64::MAX) {
prop_assert_eq!(add(a, 0), a);
prop_assert_eq!(add(0, a), a);
}
}
proptest! {
#[test]
fn property_add_associative(
a in 0u64..1000,
b in 0u64..1000,
c in 0u64..1000,
) {
let left = add(add(a, b), c);
let right = add(a, add(b, c));
prop_assert_eq!(left, right);
}
}
proptest! {
#[test]
fn property_subtract_identity(a in 0u64..u64::MAX) {
prop_assert_eq!(subtract(a, 0), a);
}
}
proptest! {
#[test]
fn property_subtract_inverse(a in 0u64..1_000_000, b in 0u64..1_000_000) {
if let Some(sum) = a.checked_add(b) {
prop_assert_eq!(subtract(sum, b), a);
}
}
}
proptest! {
#[test]
fn property_multiply_commutative(a in 0u64..100_000, b in 0u64..100_000) {
prop_assert_eq!(multiply(a, b), multiply(b, a));
}
}
proptest! {
#[test]
fn property_multiply_identity(a in 0u64..u64::MAX) {
prop_assert_eq!(multiply(a, 1), a);
prop_assert_eq!(multiply(1, a), a);
}
}
proptest! {
#[test]
fn property_multiply_zero(a in 0u64..u64::MAX) {
prop_assert_eq!(multiply(a, 0), 0);
prop_assert_eq!(multiply(0, a), 0);
}
}
proptest! {
#[test]
fn property_multiply_associative(
a in 1u64..100,
b in 1u64..100,
c in 1u64..100,
) {
let left = multiply(multiply(a, b), c);
let right = multiply(a, multiply(b, c));
prop_assert_eq!(left, right);
}
}
proptest! {
#[test]
fn property_distributive(
a in 0u64..1000,
b in 0u64..1000,
c in 0u64..1000,
) {
let left = multiply(a, add(b, c));
let right = add(multiply(a, b), multiply(a, c));
prop_assert_eq!(left, right);
}
}
}