use core::ops;
use crate::managed::Slice;
pub trait Payload {
fn payload(&self) -> &payload;
}
pub trait PayloadMut: Payload {
fn resize(&mut self, length: usize) -> Result<(), Error>;
fn reframe(&mut self, reframe: Reframe) -> Result<(), Error>;
fn payload_mut(&mut self) -> &mut payload;
}
pub struct Reframe {
pub length: usize,
pub range: ops::Range<usize>,
}
byte_wrapper! {
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct payload([u8]);
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Error {
BadSize,
}
impl payload {
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
pub fn as_bytes_mut(&mut self) -> &mut [u8] {
&mut self.0
}
pub fn as_slice(&self) -> &[u8] {
&self.0
}
pub fn as_mut_slice(&mut self) -> &mut [u8] {
&mut self.0
}
}
impl Reframe {
pub fn within_header(&mut self, header: usize) {
self.range.start = 0;
self.range.end += header;
self.length += header;
}
}
impl<'a> From<&'a [u8]> for &'a payload {
fn from(val: &'a [u8]) -> &'a payload {
payload::__from_macro_new_unchecked(val)
}
}
impl<'a> From<&'a mut [u8]> for &'a mut payload {
fn from(val: &'a mut [u8]) -> &'a mut payload {
payload::__from_macro_new_unchecked_mut(val)
}
}
impl<'a> From<&'a payload> for &'a [u8] {
fn from(val: &'a payload) -> &'a [u8] {
val.as_slice()
}
}
impl<'a> From<&'a mut payload> for &'a mut [u8] {
fn from(val: &'a mut payload) -> &'a mut [u8] {
val.as_mut_slice()
}
}
impl AsRef<[u8]> for payload {
fn as_ref(&self) -> &[u8] {
self.into()
}
}
impl AsMut<[u8]> for payload {
fn as_mut(&mut self) -> &mut [u8] {
self.into()
}
}
impl ops::Deref for payload {
type Target = [u8];
fn deref(&self) -> &[u8] {
&self.0
}
}
impl ops::DerefMut for payload {
fn deref_mut(&mut self) -> &mut [u8] {
&mut self.0
}
}
impl Payload for [u8] {
fn payload(&self) -> &payload {
self.into()
}
}
impl PayloadMut for [u8] {
fn payload_mut(&mut self) -> &mut payload {
self.into()
}
fn resize(&mut self, len: usize) -> Result<(), Error> {
if self.len() == len {
Ok(())
} else {
Err(Error::BadSize)
}
}
fn reframe(&mut self, reframe: Reframe) -> Result<(), Error> {
self.resize(reframe.length)
}
}
impl Payload for payload {
fn payload(&self) -> &payload {
self
}
}
impl PayloadMut for payload {
fn payload_mut(&mut self) -> &mut payload {
self
}
fn resize(&mut self, len: usize) -> Result<(), Error> {
self.as_mut_slice().resize(len)
}
fn reframe(&mut self, reframe: Reframe) -> Result<(), Error> {
self.resize(reframe.length)
}
}
impl<P: Payload + ?Sized> Payload for &'_ P {
fn payload(&self) -> &payload {
(**self).payload()
}
}
impl<P: Payload + ?Sized> Payload for &'_ mut P {
fn payload(&self) -> &payload {
(**self).payload()
}
}
impl<P: PayloadMut + ?Sized> PayloadMut for &'_ mut P {
fn payload_mut(&mut self) -> &mut payload {
(**self).payload_mut()
}
fn resize(&mut self, length: usize) -> Result<(), Error> {
(**self).resize(length)
}
fn reframe(&mut self, reframe: Reframe) -> Result<(), Error> {
(**self).reframe(reframe)
}
}
impl Payload for Slice<'_, u8> {
fn payload(&self) -> &payload {
self.as_slice().into()
}
}
impl PayloadMut for Slice<'_, u8> {
fn payload_mut(&mut self) -> &mut payload {
self.as_mut_slice().into()
}
fn resize(&mut self, length: usize) -> Result<(), Error> {
let inner = core::mem::replace(self, Slice::empty());
let result;
let inner = match inner {
Slice::One(one) if length != 1 => {
result = Err(Error::BadSize);
Slice::One(one)
},
Slice::One(one) => {
result = Ok(());
Slice::One(one)
},
Slice::Many(mut vec) => {
vec.resize(length, 0);
result = Ok(());
Slice::Many(vec)
},
Slice::Borrowed(inner) => {
if inner.len() >= length {
result = Ok(());
Slice::Borrowed(&mut inner[..length])
} else {
result = Err(Error::BadSize);
Slice::Borrowed(inner)
}
},
};
core::mem::replace(self, inner);
result
}
fn reframe(&mut self, reframe: Reframe) -> Result<(), Error> {
self.resize(reframe.length)
}
}
mod std_impls {
use crate::alloc::vec::Vec;
use super::{Error, Reframe, Payload, PayloadMut, payload};
impl Payload for Vec<u8> {
fn payload(&self) -> &super::payload {
self.as_slice().into()
}
}
impl PayloadMut for Vec<u8> {
fn payload_mut(&mut self) -> &mut payload {
self.as_mut_slice().into()
}
fn resize(&mut self, length: usize) -> Result<(), Error> {
Ok(self.resize(length, 0u8))
}
fn reframe(&mut self, reframe: Reframe) -> Result<(), Error> {
PayloadMut::resize(self, reframe.length)
}
}
}