use core::fmt;
pub const MAX_FIXTURE_BODY_BYTES: usize = 8_388_609;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum FixtureBodyError {
TooLarge,
OutputTooSmall,
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum FixtureBody<'a> {
Bytes(&'a [u8]),
Repeated {
byte: u8,
len: usize,
},
}
impl<'a> FixtureBody<'a> {
pub const fn new(bytes: &'a [u8]) -> Result<Self, FixtureBodyError> {
if bytes.len() > MAX_FIXTURE_BODY_BYTES {
return Err(FixtureBodyError::TooLarge);
}
Ok(Self::Bytes(bytes))
}
pub const fn repeated(byte: u8, len: usize) -> Result<Self, FixtureBodyError> {
if len > MAX_FIXTURE_BODY_BYTES {
return Err(FixtureBodyError::TooLarge);
}
Ok(Self::Repeated { byte, len })
}
#[must_use]
pub const fn len(self) -> usize {
match self {
Self::Bytes(bytes) => bytes.len(),
Self::Repeated { len, .. } => len,
}
}
#[must_use]
pub const fn is_empty(self) -> bool {
self.len() == 0
}
#[must_use]
pub const fn as_bytes(self) -> Option<&'a [u8]> {
match self {
Self::Bytes(bytes) => Some(bytes),
Self::Repeated { .. } => None,
}
}
pub fn write_to(self, output: &mut [u8]) -> Result<usize, FixtureBodyError> {
let len = self.len();
let target = output
.get_mut(..len)
.ok_or(FixtureBodyError::OutputTooSmall)?;
match self {
Self::Bytes(bytes) => target.copy_from_slice(bytes),
Self::Repeated { byte, .. } => target.fill(byte),
}
Ok(len)
}
}
impl fmt::Debug for FixtureBody<'_> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("FixtureBody")
.field("contents", &"[redacted]")
.field("len", &self.len())
.finish()
}
}