use ccp_shared::types::LocalNonce;
pub(crate) trait NonceIterable {
fn next(&mut self);
fn prev(&mut self);
}
impl NonceIterable for LocalNonce {
fn next(&mut self) {
let mut nonce_as_u64: u64 = u64::from_le_bytes(
self.as_mut()[0..std::mem::size_of::<u64>()]
.try_into()
.unwrap(),
);
nonce_as_u64 = nonce_as_u64.wrapping_add(1);
self.as_mut()[0..std::mem::size_of::<u64>()]
.copy_from_slice(&u64::to_le_bytes(nonce_as_u64));
}
fn prev(&mut self) {
let mut nonce_as_u64: u64 = u64::from_le_bytes(
self.as_mut()[0..std::mem::size_of::<u64>()]
.try_into()
.unwrap(),
);
nonce_as_u64 = nonce_as_u64.wrapping_sub(1);
self.as_mut()[0..std::mem::size_of::<u64>()]
.copy_from_slice(&u64::to_le_bytes(nonce_as_u64));
}
}
#[cfg(test)]
mod tests {
use super::LocalNonce;
use super::NonceIterable;
#[test]
fn next_works() {
let mut nonce = LocalNonce::random();
let nonce_first = nonce.as_ref();
let nonce_first_as_u64 = u64::from_le_bytes(
nonce_first[0..std::mem::size_of::<u64>()]
.try_into()
.unwrap(),
);
nonce.next();
let nonce_second = nonce.as_ref();
let nonce_second_as_u64 = u64::from_le_bytes(
nonce_second[0..std::mem::size_of::<u64>()]
.try_into()
.unwrap(),
);
assert_eq!(nonce_first_as_u64 + 1, nonce_second_as_u64);
}
#[test]
fn prev_works() {
let mut nonce = LocalNonce::random();
let nonce_first = nonce.as_ref();
let nonce_first_as_u64 = u64::from_le_bytes(
nonce_first[0..std::mem::size_of::<u64>()]
.try_into()
.unwrap(),
);
nonce.prev();
let nonce_second = nonce.as_ref();
let nonce_second_as_u64 = u64::from_le_bytes(
nonce_second[0..std::mem::size_of::<u64>()]
.try_into()
.unwrap(),
);
assert_eq!(nonce_first_as_u64 - 1, nonce_second_as_u64);
}
#[test]
fn next_prev_idempotent() {
let mut nonce = LocalNonce::random();
let nonce_first = nonce.as_ref().to_owned();
nonce.prev();
assert_ne!(&nonce_first, nonce.as_ref());
nonce.next();
let nonce_second = nonce.as_ref();
assert_eq!(&nonce_first, nonce_second);
}
#[test]
fn prev_next_idempotent() {
let mut nonce = LocalNonce::random();
let nonce_first = nonce.as_ref().to_owned();
nonce.next();
assert_ne!(&nonce_first, nonce.as_ref());
nonce.prev();
let nonce_second = nonce.as_ref();
assert_eq!(&nonce_first, nonce_second);
}
}