use core::{cmp::Ordering, ops::Add};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct SerialNumber(pub(crate) u32);
impl SerialNumber {
pub fn new(value: u32) -> Self {
Self(value)
}
pub fn get(&self) -> u32 {
self.0
}
}
impl From<u32> for SerialNumber {
fn from(value: u32) -> Self {
Self(value)
}
}
impl Add for SerialNumber {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0.wrapping_add(rhs.0))
}
}
impl PartialOrd for SerialNumber {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
const SERIAL_BITS_HALF: u32 = 1 << (u32::BITS - 1);
let i1 = self.0;
let i2 = other.0;
if i1 == i2 {
Some(Ordering::Equal)
} else if (i1 < i2 && (i2 - i1) < SERIAL_BITS_HALF)
|| (i1 > i2 && (i1 - i2) > SERIAL_BITS_HALF)
{
Some(Ordering::Less)
} else if (i1 < i2 && (i2 - i1) > SERIAL_BITS_HALF)
|| (i1 > i2 && (i1 - i2) < SERIAL_BITS_HALF)
{
Some(Ordering::Greater)
} else {
None
}
}
}