use arrayvec::ArrayVec; use super::{Count, Id, ShortEventId, ShortId, ShortRoomId}; #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub enum RawId { Normal(RawIdNormal), Backfilled(RawIdBackfilled), } type RawIdNormal = [u8; RawId::NORMAL_LEN]; type RawIdBackfilled = [u8; RawId::BACKFILLED_LEN]; const INT_LEN: usize = size_of::(); impl RawId { const BACKFILLED_LEN: usize = size_of::() + INT_LEN + size_of::(); const MAX_LEN: usize = Self::BACKFILLED_LEN; const NORMAL_LEN: usize = size_of::() + size_of::(); #[inline] #[must_use] pub fn pdu_count(&self) -> Count { let id: Id = (*self).into(); id.shorteventid } #[inline] #[must_use] pub fn shortroomid(self) -> [u8; INT_LEN] { match self { Self::Normal(raw) => raw[0..INT_LEN] .try_into() .expect("normal raw shortroomid array from slice"), Self::Backfilled(raw) => raw[0..INT_LEN] .try_into() .expect("backfilled raw shortroomid array from slice"), } } #[inline] #[must_use] pub fn shorteventid(self) -> [u8; INT_LEN] { match self { Self::Normal(raw) => raw[INT_LEN..INT_LEN * 2] .try_into() .expect("normal raw shorteventid array from slice"), Self::Backfilled(raw) => raw[INT_LEN * 2..INT_LEN * 3] .try_into() .expect("backfilled raw shorteventid array from slice"), } } #[inline] #[must_use] pub fn as_bytes(&self) -> &[u8] { match self { Self::Normal(ref raw) => raw, Self::Backfilled(ref raw) => raw, } } } impl AsRef<[u8]> for RawId { #[inline] fn as_ref(&self) -> &[u8] { self.as_bytes() } } impl From<&[u8]> for RawId { #[inline] fn from(id: &[u8]) -> Self { match id.len() { Self::NORMAL_LEN => Self::Normal( id[0..Self::NORMAL_LEN] .try_into() .expect("normal RawId from [u8]"), ), Self::BACKFILLED_LEN => Self::Backfilled( id[0..Self::BACKFILLED_LEN] .try_into() .expect("backfilled RawId from [u8]"), ), _ => unimplemented!("unrecognized RawId length"), } } } impl From for RawId { #[inline] fn from(id: Id) -> Self { const MAX_LEN: usize = RawId::MAX_LEN; type RawVec = ArrayVec; let mut vec = RawVec::new(); vec.extend(id.shortroomid.to_be_bytes()); id.shorteventid.debug_assert_valid(); match id.shorteventid { Count::Normal(shorteventid) => { vec.extend(shorteventid.to_be_bytes()); Self::Normal(vec.as_ref().try_into().expect("RawVec into RawId::Normal")) }, Count::Backfilled(shorteventid) => { vec.extend(0_u64.to_be_bytes()); vec.extend(shorteventid.to_be_bytes()); Self::Backfilled( vec.as_ref() .try_into() .expect("RawVec into RawId::Backfilled"), ) }, } } }