use serde::{Deserialize, Serialize};
use std::fmt;
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct SequenceNumber(u64);
impl fmt::Display for SequenceNumber {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl SequenceNumber {
pub fn acknowledges(self, other: SequenceNumber) -> bool {
self.0 >= other.0
}
pub fn after(self, other: SequenceNumber) -> bool {
self.0 > other.0
}
pub fn preceding(self) -> SequenceNumber {
if self.0 == 0 {
SequenceNumber(0)
} else {
SequenceNumber(self.0 - 1)
}
}
pub fn none() -> SequenceNumber {
SequenceNumber(0)
}
}
pub struct SequenceNumberGenerator {
counter: std::ops::RangeFrom<u64>,
previous: SequenceNumber,
}
impl Default for SequenceNumberGenerator {
fn default() -> Self {
Self::new()
}
}
impl SequenceNumberGenerator {
pub fn new() -> SequenceNumberGenerator {
SequenceNumberGenerator {
counter: (1..),
previous: SequenceNumber::none(),
}
}
pub fn get_next(&mut self) -> SequenceNumber {
let next = SequenceNumber((&mut self.counter).next().unwrap());
self.previous = next;
next
}
pub fn get_previous(&self) -> SequenceNumber {
self.previous
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn construct_generator() {
let mut s1 = SequenceNumberGenerator::default();
let mut s2 = SequenceNumberGenerator::new();
assert_eq!(s1.get_next(), s2.get_next());
}
#[test]
fn gets() {
let mut s = SequenceNumberGenerator::default();
assert_eq!(s.get_previous(), SequenceNumber(0));
assert_eq!(s.get_previous(), SequenceNumber(0));
assert_eq!(s.get_next(), SequenceNumber(1));
assert_eq!(s.get_next(), SequenceNumber(2));
assert_eq!(s.get_previous(), SequenceNumber(2));
assert_eq!(s.get_next(), SequenceNumber(3));
assert_eq!(s.get_previous(), SequenceNumber(3));
}
#[test]
fn seqs() {
let mut s = SequenceNumberGenerator::default();
let sn = s.get_previous();
assert_eq!(sn.preceding(), SequenceNumber(0));
assert!(!sn.after(SequenceNumber(0)));
assert!(!sn.after(SequenceNumber(1)));
assert!(sn.acknowledges(SequenceNumber(0)));
assert!(!sn.acknowledges(SequenceNumber(1)));
let sn = s.get_next();
assert_eq!(sn.preceding(), SequenceNumber(0));
assert!(sn.after(SequenceNumber(0)));
assert!(!sn.after(SequenceNumber(1)));
assert!(sn.acknowledges(SequenceNumber(0)));
assert!(sn.acknowledges(SequenceNumber(1)));
let sn = s.get_next();
assert_eq!(sn.preceding(), SequenceNumber(1));
assert!(sn.after(SequenceNumber(0)));
assert!(sn.after(SequenceNumber(1)));
assert!(!sn.after(SequenceNumber(2)));
assert!(sn.acknowledges(SequenceNumber(0)));
assert!(sn.acknowledges(SequenceNumber(1)));
assert!(sn.acknowledges(SequenceNumber(2)));
assert!(!sn.acknowledges(SequenceNumber(3)));
}
#[test]
fn display() {
assert_eq!(SequenceNumber(123).to_string(), "123");
}
}