pipecircuit 0.0.18

Correct. Robust. Fast. Portable. Pick four.
Documentation
use super::change::{ProjectionChange, projection_change};

#[kani::proof]
fn projection_change_reconstructs_the_exact_new_state() {
    let before: Option<(u64, u8)> = kani::any();
    let after: Option<(u64, u8)> = kani::any();
    let change = projection_change(
        before
            .as_ref()
            .map(|(incarnation, value)| (*incarnation, value)),
        after
            .as_ref()
            .map(|(incarnation, value)| (*incarnation, value)),
    );
    let reconstructed = match change {
        ProjectionChange::Unchanged => {
            assert!(before == after);
            kani::cover!(true, "observed.change_unchanged");
            before
        }
        ProjectionChange::Upsert => {
            assert!(after.is_some() && before != after);
            kani::cover!(true, "observed.change_upsert");
            after
        }
        ProjectionChange::Remove { incarnation } => {
            assert!(matches!(before, Some((old, _)) if old == incarnation));
            assert!(after.is_none());
            kani::cover!(true, "observed.change_remove");
            None
        }
    };
    assert!(reconstructed == after);
}