use elicitation::*;
#[kani::proof]
fn verify_vec_non_empty() {
let empty: Vec<i32> = vec![];
let result = VecNonEmpty::new(empty);
assert!(result.is_err(), "Empty vec rejected");
let non_empty = vec![42];
let result = VecNonEmpty::new(non_empty);
assert!(result.is_ok(), "Non-empty vec accepted");
}
#[kani::proof]
fn verify_vec_all_satisfy() {
let vec_positive = vec![1i8, 2, 3];
for &elem in &vec_positive {
assert!(elem > 0, "All elements positive");
}
}
#[kani::proof]
fn verify_hashmap_wrapper_logic() {
let _err = ValidationError::EmptyCollection;
}
#[kani::proof]
fn verify_btreemap_non_empty() {
let _err = ValidationError::EmptyCollection;
}
#[kani::proof]
fn verify_hashset_non_empty() {
let _err = ValidationError::EmptyCollection;
}
#[kani::proof]
fn verify_btreeset_non_empty() {
let _err = ValidationError::EmptyCollection;
}
#[kani::proof]
fn verify_vecdeque_non_empty() {
let _err = ValidationError::EmptyCollection;
}
#[kani::proof]
fn verify_linkedlist_non_empty() {
let _err = ValidationError::EmptyCollection;
}
#[kani::proof]
fn verify_box_satisfies() {
let positive = I8Positive::new(42).unwrap();
let _boxed = BoxSatisfies::new(positive);
}
#[kani::proof]
fn verify_arc_satisfies() {
let positive = I8Positive::new(42).unwrap();
let _arc = ArcSatisfies::new(positive);
}
#[kani::proof]
fn verify_rc_satisfies() {
let positive = I8Positive::new(42).unwrap();
let _rc = RcSatisfies::new(positive);
}
#[kani::proof]
fn verify_result_ok() {
let ok_val = 42i32;
let result: Result<i32, String> = Ok(ok_val);
let wrapped = ResultOk::new(result);
assert!(wrapped.is_ok(), "Ok variant accepted");
let err_val: Result<i32, String> = Err(String::from("e")); let wrapped = ResultOk::new(err_val);
assert!(wrapped.is_err(), "Err variant rejected");
}
#[kani::proof]
fn verify_tuple3_composition() {
let a = I8Positive::new(1).unwrap();
let b = I8Positive::new(2).unwrap();
let c = I8Positive::new(3).unwrap();
let tuple = Tuple3::new(a, b, c);
assert!(tuple.0.get() > 0, "First element positive");
assert!(tuple.1.get() > 0, "Second element positive");
assert!(tuple.2.get() > 0, "Third element positive");
}
#[kani::proof]
fn verify_tuple4_composition() {
let a = I8Positive::new(1).unwrap();
let b = I8Positive::new(2).unwrap();
let c = I8Positive::new(3).unwrap();
let d = I8Positive::new(4).unwrap();
let tuple = Tuple4::new(a, b, c, d);
assert!(tuple.0.get() > 0, "First element positive");
assert!(tuple.1.get() > 0, "Second element positive");
assert!(tuple.2.get() > 0, "Third element positive");
assert!(tuple.3.get() > 0, "Fourth element positive");
}
#[cfg(feature = "serde_json")]
#[kani::proof]
fn verify_value_object() {
let _err = ValidationError::WrongJsonType {
expected: "object".to_string(),
got: "other".to_string(),
};
}
#[cfg(feature = "serde_json")]
#[kani::proof]
fn verify_value_array() {
let _err = ValidationError::WrongJsonType {
expected: "array".to_string(),
got: "other".to_string(),
};
}
#[cfg(feature = "serde_json")]
#[kani::proof]
fn verify_value_non_null() {
let _err = ValidationError::JsonIsNull;
}
#[cfg(feature = "chrono")]
#[kani::proof]
fn verify_datetime_utc_after() {
let _err = ValidationError::DateTimeTooEarly {
value: "value".to_string(),
threshold: "threshold".to_string(),
};
}
#[cfg(feature = "chrono")]
#[kani::proof]
fn verify_datetime_utc_before() {
let _err = ValidationError::DateTimeTooLate {
value: "value".to_string(),
threshold: "threshold".to_string(),
};
}
#[cfg(feature = "jiff")]
#[kani::proof]
fn verify_timestamp_after() {
let _err = ValidationError::DateTimeTooEarly {
value: "value".to_string(),
threshold: "threshold".to_string(),
};
}
#[cfg(feature = "jiff")]
#[kani::proof]
fn verify_timestamp_before() {
let _err = ValidationError::DateTimeTooLate {
value: "value".to_string(),
threshold: "threshold".to_string(),
};
}
#[cfg(feature = "time")]
#[kani::proof]
fn verify_offset_datetime_after() {
let _err = ValidationError::DateTimeTooEarly {
value: "value".to_string(),
threshold: "threshold".to_string(),
};
}
#[cfg(feature = "time")]
#[kani::proof]
fn verify_offset_datetime_before() {
let _err = ValidationError::DateTimeTooLate {
value: "value".to_string(),
threshold: "threshold".to_string(),
};
}
#[kani::proof]
fn verify_i8_range_concrete() {
const MIN: i8 = -10;
const MAX: i8 = 10;
let value: i8 = kani::any();
match I8Range::<MIN, MAX>::new(value) {
Ok(range) => {
assert!(value >= MIN, "Value >= MIN");
assert!(value <= MAX, "Value <= MAX");
assert!(range.get() >= MIN, "Accessor preserves lower bound");
assert!(range.get() <= MAX, "Accessor preserves upper bound");
}
Err(_) => {
assert!(
value < MIN || value > MAX,
"Construction rejects out-of-range"
);
}
}
}
#[kani::proof]
fn verify_i8_range_positive() {
const MIN: i8 = 1;
const MAX: i8 = 100;
let value: i8 = kani::any();
match I8Range::<MIN, MAX>::new(value) {
Ok(_range) => {
assert!(value >= MIN && value <= MAX, "I8Range[1,100] invariant");
}
Err(_) => {
assert!(value < MIN || value > MAX, "Out of range rejected");
}
}
}
#[kani::proof]
fn verify_u8_range_concrete() {
const MIN: u8 = 10;
const MAX: u8 = 200;
let value: u8 = kani::any();
match U8Range::<MIN, MAX>::new(value) {
Ok(range) => {
assert!(value >= MIN, "Value >= MIN");
assert!(value <= MAX, "Value <= MAX");
assert!(range.get() >= MIN, "Accessor preserves bounds");
assert!(range.get() <= MAX, "Accessor preserves bounds");
}
Err(_) => {
assert!(value < MIN || value > MAX, "Out of range rejected");
}
}
}
#[kani::proof]
fn verify_i8_range_singleton() {
const MIN: i8 = 42;
const MAX: i8 = 42;
let value: i8 = kani::any();
match I8Range::<MIN, MAX>::new(value) {
Ok(_range) => {
assert!(value == 42, "Singleton range accepts only exact value");
}
Err(_) => {
assert!(value != 42, "Singleton rejects all other values");
}
}
}
#[kani::proof]
fn verify_i16_range_concrete() {
const MIN: i16 = -1000;
const MAX: i16 = 1000;
let value: i16 = kani::any();
match I16Range::<MIN, MAX>::new(value) {
Ok(range) => {
assert!(value >= MIN && value <= MAX, "I16Range invariant");
assert!(
range.get() >= MIN && range.get() <= MAX,
"Accessor preserves"
);
}
Err(_) => {
assert!(value < MIN || value > MAX, "Rejection correct");
}
}
}
#[kani::proof]
fn verify_u16_range_concrete() {
const MIN: u16 = 100;
const MAX: u16 = 60000;
let value: u16 = kani::any();
match U16Range::<MIN, MAX>::new(value) {
Ok(_range) => {
assert!(value >= MIN && value <= MAX, "U16Range invariant");
}
Err(_) => {
assert!(value < MIN || value > MAX, "Rejection correct");
}
}
}
#[kani::proof]
fn verify_i32_positive() {
let value: i32 = kani::any();
match I32Positive::new(value) {
Ok(positive) => {
assert!(value > 0, "I32Positive invariant: value > 0");
assert!(positive.get() > 0, "Accessor preserves");
assert!(positive.into_inner() > 0, "Unwrap preserves");
}
Err(_) => {
assert!(value <= 0, "Construction rejects non-positive");
}
}
}
#[kani::proof]
fn verify_i32_non_negative() {
let value: i32 = kani::any();
match I32NonNegative::new(value) {
Ok(non_neg) => {
assert!(value >= 0, "I32NonNegative invariant: value >= 0");
assert!(non_neg.get() >= 0, "Accessor preserves");
assert!(non_neg.into_inner() >= 0, "Unwrap preserves");
}
Err(_) => {
assert!(value < 0, "Construction rejects negative");
}
}
}
#[kani::proof]
fn verify_i32_range() {
const MIN: i32 = -1000;
const MAX: i32 = 1000;
let value: i32 = kani::any();
match I32Range::<MIN, MAX>::new(value) {
Ok(range) => {
assert!(value >= MIN && value <= MAX, "I32Range invariant");
assert!(
range.get() >= MIN && range.get() <= MAX,
"Accessor preserves"
);
}
Err(_) => {
assert!(value < MIN || value > MAX, "Out of range rejected");
}
}
}
#[kani::proof]
fn verify_i64_positive() {
let value: i64 = kani::any();
match I64Positive::new(value) {
Ok(positive) => {
assert!(value > 0, "I64Positive invariant");
assert!(positive.get() > 0, "Accessor preserves");
assert!(positive.into_inner() > 0, "Unwrap preserves");
}
Err(_) => {
assert!(value <= 0, "Construction rejects non-positive");
}
}
}
#[kani::proof]
fn verify_i64_non_negative() {
let value: i64 = kani::any();
match I64NonNegative::new(value) {
Ok(_non_neg) => {
assert!(value >= 0, "I64NonNegative invariant");
}
Err(_) => {
assert!(value < 0, "Construction rejects negative");
}
}
}
#[kani::proof]
fn verify_i64_range() {
const MIN: i64 = -100000;
const MAX: i64 = 100000;
let value: i64 = kani::any();
match I64Range::<MIN, MAX>::new(value) {
Ok(_range) => {
assert!(value >= MIN && value <= MAX, "I64Range invariant");
}
Err(_) => {
assert!(value < MIN || value > MAX, "Rejection correct");
}
}
}
#[kani::proof]
fn verify_i128_positive() {
let value: i128 = kani::any();
match I128Positive::new(value) {
Ok(_positive) => {
assert!(value > 0, "I128Positive invariant");
}
Err(_) => {
assert!(value <= 0, "Construction rejects non-positive");
}
}
}
#[kani::proof]
fn verify_i128_non_negative() {
let value: i128 = kani::any();
match I128NonNegative::new(value) {
Ok(_non_neg) => {
assert!(value >= 0, "I128NonNegative invariant");
}
Err(_) => {
assert!(value < 0, "Construction rejects negative");
}
}
}
#[kani::proof]
fn verify_i128_range() {
const MIN: i128 = -1000000;
const MAX: i128 = 1000000;
let value: i128 = kani::any();
match I128Range::<MIN, MAX>::new(value) {
Ok(_range) => {
assert!(value >= MIN && value <= MAX, "I128Range invariant");
}
Err(_) => {
assert!(value < MIN || value > MAX, "Rejection correct");
}
}
}
#[kani::proof]
fn verify_u32_non_zero() {
let value: u32 = kani::any();
match U32NonZero::new(value) {
Ok(non_zero) => {
assert!(value != 0, "U32NonZero invariant: value != 0");
assert!(non_zero.get() != 0, "Accessor preserves");
assert!(non_zero.into_inner() != 0, "Unwrap preserves");
}
Err(_) => {
assert!(value == 0, "Construction rejects zero");
}
}
}
#[kani::proof]
fn verify_u32_range() {
const MIN: u32 = 100;
const MAX: u32 = 1000000;
let value: u32 = kani::any();
match U32Range::<MIN, MAX>::new(value) {
Ok(_range) => {
assert!(value >= MIN && value <= MAX, "U32Range invariant");
}
Err(_) => {
assert!(value < MIN || value > MAX, "Out of range rejected");
}
}
}
#[kani::proof]
fn verify_u64_non_zero() {
let value: u64 = kani::any();
match U64NonZero::new(value) {
Ok(_non_zero) => {
assert!(value != 0, "U64NonZero invariant");
}
Err(_) => {
assert!(value == 0, "Construction rejects zero");
}
}
}
#[kani::proof]
fn verify_u64_range() {
const MIN: u64 = 1000;
const MAX: u64 = 1000000000;
let value: u64 = kani::any();
match U64Range::<MIN, MAX>::new(value) {
Ok(_range) => {
assert!(value >= MIN && value <= MAX, "U64Range invariant");
}
Err(_) => {
assert!(value < MIN || value > MAX, "Rejection correct");
}
}
}
#[kani::proof]
fn verify_u128_non_zero() {
let value: u128 = kani::any();
match U128NonZero::new(value) {
Ok(_non_zero) => {
assert!(value != 0, "U128NonZero invariant");
}
Err(_) => {
assert!(value == 0, "Construction rejects zero");
}
}
}
#[kani::proof]
fn verify_u128_range() {
const MIN: u128 = 1000;
const MAX: u128 = 1000000000000;
let value: u128 = kani::any();
match U128Range::<MIN, MAX>::new(value) {
Ok(_range) => {
assert!(value >= MIN && value <= MAX, "U128Range invariant");
}
Err(_) => {
assert!(value < MIN || value > MAX, "Rejection correct");
}
}
}
#[kani::proof]
fn verify_isize_positive() {
let value: isize = kani::any();
match IsizePositive::new(value) {
Ok(positive) => {
assert!(value > 0, "IsizePositive invariant");
assert!(positive.get() > 0, "Accessor preserves");
assert!(positive.into_inner() > 0, "Unwrap preserves");
}
Err(_) => {
assert!(value <= 0, "Construction rejects non-positive");
}
}
}
#[kani::proof]
fn verify_isize_non_negative() {
let value: isize = kani::any();
match IsizeNonNegative::new(value) {
Ok(_non_neg) => {
assert!(value >= 0, "IsizeNonNegative invariant");
}
Err(_) => {
assert!(value < 0, "Construction rejects negative");
}
}
}
#[kani::proof]
fn verify_isize_range() {
const MIN: isize = -10000;
const MAX: isize = 10000;
let value: isize = kani::any();
match IsizeRange::<MIN, MAX>::new(value) {
Ok(_range) => {
assert!(value >= MIN && value <= MAX, "IsizeRange invariant");
}
Err(_) => {
assert!(value < MIN || value > MAX, "Rejection correct");
}
}
}
#[kani::proof]
fn verify_usize_non_zero() {
let value: usize = kani::any();
match UsizeNonZero::new(value) {
Ok(non_zero) => {
assert!(value != 0, "UsizeNonZero invariant");
assert!(non_zero.get() != 0, "Accessor preserves");
assert!(non_zero.into_inner() != 0, "Unwrap preserves");
}
Err(_) => {
assert!(value == 0, "Construction rejects zero");
}
}
}
#[kani::proof]
fn verify_usize_range() {
const MIN: usize = 10;
const MAX: usize = 100000;
let value: usize = kani::any();
match UsizeRange::<MIN, MAX>::new(value) {
Ok(_range) => {
assert!(value >= MIN && value <= MAX, "UsizeRange invariant");
}
Err(_) => {
assert!(value < MIN || value > MAX, "Rejection correct");
}
}
}
#[kani::proof]
fn verify_ipv4() {
use std::net::{IpAddr, Ipv4Addr};
let v4_addr = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1));
let result = IpV4::new(v4_addr);
assert!(result.is_ok(), "IpV4 accepts IPv4 addresses");
let v6_addr = IpAddr::V6(std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
let result = IpV4::new(v6_addr);
assert!(result.is_err(), "IpV4 rejects IPv6 addresses");
}
#[kani::proof]
fn verify_ipv6() {
use std::net::{IpAddr, Ipv6Addr};
let v6_addr = IpAddr::V6(Ipv6Addr::new(0x2001, 0x0db8, 0, 0, 0, 0, 0, 1));
let result = IpV6::new(v6_addr);
assert!(result.is_ok(), "IpV6 accepts IPv6 addresses");
let v4_addr = IpAddr::V4(std::net::Ipv4Addr::new(192, 168, 1, 1));
let result = IpV6::new(v4_addr);
assert!(result.is_err(), "IpV6 rejects IPv4 addresses");
}
#[cfg(feature = "chrono")]
#[kani::proof]
fn verify_naive_datetime_after() {
let _err = ValidationError::DateTimeTooEarly {
value: "value".to_string(),
threshold: "threshold".to_string(),
};
}
#[kani::proof]
fn verify_array_all_satisfy() {
let arr = [
I8Positive::new(1).unwrap(),
I8Positive::new(2).unwrap(),
I8Positive::new(3).unwrap(),
];
let arr_contract = ArrayAllSatisfy::<I8Positive, 3>::new(arr);
for elem in arr_contract.get() {
assert!(elem.get() > 0, "All elements positive");
}
}