pipecircuit 0.0.23

Correct. Robust. Fast. Portable. Pick four.
Documentation
use core::num::{NonZeroU32, NonZeroU64};

use crate::{TimerIn, TimerOut, storage::warp_table::Capacity};

use super::*;

#[kani::proof]
#[kani::unwind(10)]
fn an_armed_delayed_message_is_released_exactly_once() {
    let capacity = Capacity::new(NonZeroU32::MIN);
    let Ok(mut ledger) = DelayLedger::try_new(capacity) else {
        return;
    };
    let DelayAdmissionOutcome::Admitted { admission } = ledger.admit(Delayed::new(
        kani::any::<u8>(),
        WakeAfter::nanoseconds(NonZeroU64::MIN),
    )) else {
        assert!(false, "empty delay ledger must admit one item");
        return;
    };
    let TimerIn::Arm { token, .. } = admission.timer_input() else {
        assert!(false, "new delay admission must request a timer arm");
        return;
    };
    let Ok(armed) = (TimerOut::Armed { token }).into_arm_outcome() else {
        assert!(false, "armed timer output must convert to an arm outcome");
        return;
    };
    let Ok(DelayArmOutcome::Armed) = admission.settle_timer_arm(armed) else {
        assert!(false, "matching timer arm must arm the delayed message");
        return;
    };

    kani::cover!(true, "delay.armed");
    assert!(matches!(
        ledger.release(token),
        DelayReleaseOutcome::Released { .. }
    ));
    assert!(matches!(
        ledger.release(token),
        DelayReleaseOutcome::Stale { .. }
    ));
    assert!(ledger.is_empty());
}