use core::ops::{Add, AddAssign, Sub};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
pub struct DiffIndex(#[serde(with = "postcard::fixint::le")] u16);
impl DiffIndex {
pub const MAX_NEWER_DISTANCE: u16 = u16::MAX / 2;
#[inline]
pub fn new(value: u16) -> Self {
Self(value)
}
#[inline]
pub fn get(self) -> u16 {
self.0
}
pub fn is_newer_than(self, other: Self) -> bool {
let distance = self.distance_after(other);
distance != 0 && distance <= Self::MAX_NEWER_DISTANCE
}
#[inline]
pub fn distance_after(self, base: Self) -> u16 {
self.0.wrapping_sub(base.0)
}
}
impl Add<u16> for DiffIndex {
type Output = Self;
#[inline]
fn add(self, rhs: u16) -> Self::Output {
Self(self.0.wrapping_add(rhs))
}
}
impl AddAssign<u16> for DiffIndex {
fn add_assign(&mut self, rhs: u16) {
*self = *self + rhs;
}
}
impl Sub<u16> for DiffIndex {
type Output = Self;
#[inline]
fn sub(self, rhs: u16) -> Self::Output {
Self(self.0.wrapping_sub(rhs))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn comparison() {
assert_eq!(DiffIndex::new(0), DiffIndex::new(0));
assert!(DiffIndex::new(1).is_newer_than(DiffIndex::new(0)));
assert!(DiffIndex::new(0).is_newer_than(DiffIndex::new(u16::MAX)));
}
}