use rkyv::{rancor::Fallible, ser::Writer};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[must_use]
pub struct VersionedBytes<'a> {
pub format_identifier: [u8; 24],
pub version: u64,
pub data: &'a [u8],
}
impl<'a> VersionedBytes<'a> {
#[allow(clippy::missing_panics_doc, reason = "Should never panic")]
#[must_use]
#[inline]
pub fn try_from_bytes(value: &'a [u8], format_identifier: [u8; 24]) -> Option<Self> {
if value.starts_with(&format_identifier) && value.len() >= 32 {
let (version_bytes, data) = value[24..].split_at(8);
Some(Self {
format_identifier,
version: u64::from_le_bytes(version_bytes.try_into().unwrap()),
data,
})
} else {
None
}
}
#[must_use]
#[inline]
pub const fn output_length(&self) -> usize {
32_usize.strict_add(self.data.len())
}
#[inline]
pub fn write_header<W>(&self, writer: &mut W) -> Result<(), <W as Fallible>::Error>
where
W: Writer + Fallible,
{
writer.write(&self.format_identifier)?;
writer.write(&self.version.to_le_bytes())?;
Ok(())
}
#[inline]
pub fn write<W>(&self, writer: &mut W) -> Result<(), <W as Fallible>::Error>
where
W: Writer + Fallible,
{
writer.write(&self.format_identifier)?;
writer.write(&self.version.to_le_bytes())?;
writer.write(self.data)?;
Ok(())
}
}