use bincode::{
de::Decoder,
enc::Encoder,
error::{AllowedEnumVariants, DecodeError, EncodeError},
Decode, Encode,
};
#[derive(Clone, Copy, Default, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
#[repr(transparent)]
pub struct U31(u32);
impl U31 {
pub const MAX: Self = Self(0x7fff_ffff);
#[inline(always)]
pub const fn new(x: u32) -> Option<Self> {
if x <= Self::MAX.get() {
Some(Self(x))
} else {
None
}
}
#[inline(always)]
pub const fn get(self) -> u32 {
self.0
}
}
const U31_VALID_RANGE: AllowedEnumVariants = AllowedEnumVariants::Range {
min: 0,
max: U31::MAX.get(),
};
impl<Context> Decode<Context> for U31 {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
let x = Decode::decode(decoder)?;
Self::new(x).ok_or(DecodeError::UnexpectedVariant {
type_name: "U31",
allowed: &U31_VALID_RANGE,
found: x,
})
}
}
bincode::impl_borrow_decode!(U31);
impl Encode for U31 {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
Encode::encode(&self.0, encoder)?;
Ok(())
}
}