use super::*;
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
struct Revision(u8);
impl SynchronizedViewRevision for Revision {
type ChangeId = u8;
fn changed_through(change_id: Self::ChangeId) -> Self {
Self(change_id)
}
fn next_change_id(self) -> Option<Self::ChangeId> {
self.0.checked_add(1)
}
}
#[kani::proof]
fn change_classification_is_exact() {
let synchronized_through = Revision(kani::any());
let change_id = kani::any();
let mut view = SynchronizedView::new(Revision(0));
let _ = view.apply_snapshot(synchronized_through, ());
match view.apply_change(change_id, |_| Ok::<(), ()>(()), |_, _| Ok(()), |_, ()| {}) {
ApplySynchronizedViewChangeOutcome::Applied { through } => {
assert!(synchronized_through.next_change_id() == Some(change_id));
assert!(through == Revision(change_id));
}
ApplySynchronizedViewChangeOutcome::Stale {
change_through,
synchronized_through,
} => {
assert!(change_through <= synchronized_through);
}
ApplySynchronizedViewChangeOutcome::SnapshotRequired {
observed_through,
reason:
SynchronizedViewSnapshotRequiredReason::ChangeGap {
synchronized_through,
},
} => {
assert!(change_id > synchronized_through.0);
assert!(synchronized_through.next_change_id() != Some(change_id));
assert!(observed_through == Revision(change_id));
}
ApplySynchronizedViewChangeOutcome::SnapshotRequired { .. } => unreachable!(),
}
}