use crate::Error;
use core::{cmp, fmt, iter, mem};
pub struct BytesOr<'a, T: ?Sized>(Inner<'a, T>);
impl<'a, T: ?Sized> From<&'a T> for BytesOr<'a, T> {
fn from(r: &'a T) -> Self {
BytesOr(Inner::Or(r))
}
}
enum Inner<'a, T: ?Sized> {
Bytes(&'a [u8]),
Or(&'a T),
}
impl<'a, T: ?Sized> Clone for Inner<'a, T> {
fn clone(&self) -> Self {
match self {
Inner::Bytes(b) => Inner::Bytes(b),
Inner::Or(t) => Inner::Or(t),
}
}
}
impl<'a, T: ?Sized> Clone for BytesOr<'a, T> {
fn clone(&self) -> Self {
BytesOr(self.0)
}
}
impl<'a, T: ?Sized> Copy for BytesOr<'a, T> {}
impl<'a, T: ?Sized> Copy for Inner<'a, T> {}
impl<'a, T: fmt::Debug + FromBytes<'a> + Copy> fmt::Debug for BytesOr<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.read().fmt(f)
}
}
impl<'a, T: fmt::Debug + FromBytes<'a> + Copy> fmt::Debug for BytesOr<'a, [T]> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.iter()).finish()
}
}
impl<'a, T: ?Sized> BytesOr<'a, T> {
pub fn from_ref(value: &'a T) -> Self {
BytesOr(Inner::Or(value))
}
}
impl<'a, T: FromBytes<'a>> FromBytes<'a> for BytesOr<'a, T> {
fn from_bytes(bytes: &mut ByteReader<'a>) -> Result<Self, Error> {
let raw = bytes.as_raw_bytes();
T::from_bytes(bytes)?;
let used = raw.len() - bytes.bytes_left();
Ok(BytesOr(Inner::Bytes(&raw[..used])))
}
}
impl<'a, T: FromBytes<'a>> FromBytes<'a> for BytesOr<'a, [T]> {
fn from_bytes(bytes: &mut ByteReader<'a>) -> Result<Self, Error> {
let raw = bytes.as_raw_bytes();
while !bytes.is_empty() {
T::from_bytes(bytes)?;
}
Ok(BytesOr(Inner::Bytes(raw)))
}
}
impl<'a, T: ToBytes + ?Sized> ToBytes for BytesOr<'a, T> {
fn to_bytes(&self, buffer: &mut ByteWriter<'_>) -> Result<(), Error> {
match self.0 {
Inner::Bytes(b) => buffer.write_slice(b),
Inner::Or(t) => t.to_bytes(buffer),
}
}
}
impl<'a, T: Copy + FromBytes<'a>> BytesOr<'a, T> {
pub fn read(&self) -> T {
match self.0 {
Inner::Bytes(b) => {
let mut bytes = ByteReader::new(b);
let t = T::from_bytes(&mut bytes).unwrap();
assert!(bytes.is_empty());
t
}
Inner::Or(t) => *t,
}
}
}
impl<'a, T: Copy + FromBytes<'a>> BytesOr<'a, T> {
pub fn iter(&self) -> impl Iterator<Item = T> + 'a {
iter::once(self.read())
}
}
impl<'a, T: Copy + FromBytes<'a>> BytesOr<'a, [T]> {
pub fn iter(&self) -> impl Iterator<Item = T> + 'a {
IterBytesOr { inner: *self }
}
}
struct IterBytesOr<'a, T> {
inner: BytesOr<'a, [T]>,
}
impl<'a, T: Copy + FromBytes<'a>> Iterator for IterBytesOr<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
match &mut self.inner.0 {
Inner::Bytes(b) => {
if b.is_empty() {
None
} else {
let mut reader = ByteReader::new(*b);
let t = T::from_bytes(&mut reader).unwrap();
*b = reader.into_rest();
Some(t)
}
}
Inner::Or(slice) => {
let (first, rest) = slice.split_first()?;
*slice = rest;
Some(*first)
}
}
}
}
pub struct ByteWriter<'a>(&'a mut [u8]);
impl<'a> ByteWriter<'a> {
pub fn new(buf: &'a mut [u8]) -> Self {
ByteWriter(buf)
}
pub fn into_rest(self) -> &'a mut [u8] {
self.0
}
pub fn rest(&mut self) -> &mut [u8] {
self.0
}
pub fn skip(&mut self, bytes: usize) -> Result<(), Error> {
if self.space_left() < bytes {
Err(Error::Eof)
} else {
let this = mem::replace(&mut self.0, &mut []);
self.0 = &mut this[bytes..];
Ok(())
}
}
#[must_use = "data from ByteWriter will contain garbage if not used (use skip() if this is intended)"]
pub fn split_off(&mut self, len: usize) -> Result<Self, Error> {
if self.space_left() < len {
Err(Error::Eof)
} else {
let this = mem::replace(&mut self.0, &mut []);
let (head, tail) = this.split_at_mut(len);
self.0 = tail;
Ok(ByteWriter::new(head))
}
}
pub fn split_next_mut(&mut self) -> Option<&'a mut u8> {
let this = mem::replace(&mut self.0, &mut []);
if this.is_empty() {
self.0 = this;
None
} else {
let (first, rest) = this.split_first_mut().unwrap();
self.0 = rest;
Some(first)
}
}
pub fn space_left(&self) -> usize {
self.0.len()
}
pub fn write_slice(&mut self, other: &[u8]) -> Result<(), Error> {
if self.space_left() < other.len() {
Err(Error::Eof)
} else {
self.0[..other.len()].copy_from_slice(other);
let this = mem::replace(&mut self.0, &mut []);
self.0 = &mut this[other.len()..];
Ok(())
}
}
pub fn write_slice_truncate(&mut self, other: &[u8]) -> usize {
let num = cmp::min(self.space_left(), other.len());
let other = &other[..num];
self.write_slice(other).unwrap();
num
}
pub fn write_u8(&mut self, byte: u8) -> Result<(), Error> {
let first = self.split_next_mut().ok_or(Error::Eof)?;
*first = byte;
Ok(())
}
pub fn write_u16_le(&mut self, value: u16) -> Result<(), Error> {
self.write_slice(&value.to_le_bytes())
}
pub fn write_u32_le(&mut self, value: u32) -> Result<(), Error> {
self.write_slice(&value.to_le_bytes())
}
pub fn write_u64_le(&mut self, value: u64) -> Result<(), Error> {
self.write_slice(&value.to_le_bytes())
}
}
pub struct ByteReader<'a>(&'a [u8]);
impl<'a> ByteReader<'a> {
pub fn new(bytes: &'a [u8]) -> Self {
ByteReader(bytes)
}
pub fn as_raw_bytes(&self) -> &'a [u8] {
self.0
}
pub fn into_rest(self) -> &'a [u8] {
self.0
}
pub fn skip(&mut self, bytes: usize) -> Result<(), Error> {
if self.bytes_left() < bytes {
Err(Error::Eof)
} else {
self.0 = &self.0[bytes..];
Ok(())
}
}
#[must_use = "data from ByteReader will be ignored if not used (use skip() if this is intended)"]
pub fn split_off(&mut self, len: usize) -> Result<Self, Error> {
if self.bytes_left() < len {
Err(Error::Eof)
} else {
let (head, tail) = (&self.0[..len], &self.0[len..]);
self.0 = tail;
Ok(ByteReader::new(head))
}
}
pub fn bytes_left(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn read_slice(&mut self, len: usize) -> Result<&'a [u8], Error> {
if self.bytes_left() < len {
Err(Error::Eof)
} else {
let slice = &self.0[..len];
self.0 = &self.0[len..];
Ok(slice)
}
}
pub fn read_array<S>(&mut self) -> Result<S, Error>
where
S: Default + AsMut<[u8]>,
{
let mut buf = S::default();
let slice = buf.as_mut();
if self.bytes_left() < slice.len() {
return Err(Error::Eof);
}
slice.copy_from_slice(&self.0[..slice.len()]);
self.0 = &self.0[slice.len()..];
Ok(buf)
}
pub fn read_rest(&mut self) -> &'a [u8] {
let rest = self.0;
self.0 = &[];
rest
}
pub fn read_u8(&mut self) -> Result<u8, Error> {
Ok(self.read_array::<[u8; 1]>()?[0])
}
pub fn read_u16_le(&mut self) -> Result<u16, Error> {
let arr = self.read_array::<[u8; 2]>()?;
Ok(u16::from_le_bytes(arr))
}
pub fn read_u32_le(&mut self) -> Result<u32, Error> {
let arr = self.read_array::<[u8; 4]>()?;
Ok(u32::from_le_bytes(arr))
}
pub fn read_u64_le(&mut self) -> Result<u64, Error> {
let arr = self.read_array::<[u8; 8]>()?;
Ok(u64::from_le_bytes(arr))
}
}
pub trait ToBytes {
fn to_bytes(&self, writer: &mut ByteWriter<'_>) -> Result<(), Error>;
}
pub trait FromBytes<'a>: Sized {
fn from_bytes(bytes: &mut ByteReader<'a>) -> Result<Self, Error>;
}
impl<T: ToBytes> ToBytes for [T] {
fn to_bytes(&self, writer: &mut ByteWriter<'_>) -> Result<(), Error> {
for t in self {
t.to_bytes(writer)?;
}
Ok(())
}
}
impl<'a> ToBytes for &'a [u8] {
fn to_bytes(&self, writer: &mut ByteWriter<'_>) -> Result<(), Error> {
writer.write_slice(*self)
}
}
impl<'a> FromBytes<'a> for &'a [u8] {
fn from_bytes(bytes: &mut ByteReader<'a>) -> Result<Self, Error> {
Ok(bytes.read_rest())
}
}
impl<'a> FromBytes<'a> for u8 {
fn from_bytes(bytes: &mut ByteReader<'a>) -> Result<Self, Error> {
bytes.read_u8()
}
}