use core::ops::Index;
use core::ops::IndexMut;
use crate::prelude::*;
pub trait SerOutput {
type Output;
fn try_extend(&mut self, data: &[u8]) -> core::result::Result<(), ()> {
data.iter()
.try_for_each(|d| self.try_push(*d))
.map_err(|_| ())
}
fn try_push(&mut self, data: u8) -> core::result::Result<(), ()>;
fn release(self) -> core::result::Result<Self::Output, ()>;
}
pub struct SliceOutput<'a> {
buf: &'a mut [u8],
idx: usize,
}
impl<'a> SliceOutput<'a> {
pub fn new(buf: &'a mut [u8]) -> Self {
SliceOutput { buf, idx: 0 }
}
}
impl<'a> SerOutput for SliceOutput<'a> {
type Output = &'a mut [u8];
fn try_extend(&mut self, data: &[u8]) -> core::result::Result<(), ()> {
let len = data.len();
if (len + self.idx) > self.buf.len() {
return Err(());
}
self.buf[self.idx..self.idx + len].copy_from_slice(data);
self.idx += len;
Ok(())
}
fn try_push(&mut self, data: u8) -> core::result::Result<(), ()> {
if self.idx >= self.buf.len() {
return Err(());
}
self.buf[self.idx] = data;
self.idx += 1;
Ok(())
}
fn release(self) -> core::result::Result<Self::Output, ()> {
let (used, _unused) = self.buf.split_at_mut(self.idx);
Ok(used)
}
}
impl<'a> Index<usize> for SliceOutput<'a> {
type Output = u8;
fn index(&self, idx: usize) -> &u8 {
&self.buf[idx]
}
}
impl<'a> IndexMut<usize> for SliceOutput<'a> {
fn index_mut(&mut self, idx: usize) -> &mut u8 {
&mut self.buf[idx]
}
}
pub struct VecOutput(pub Vec<u8>);
impl VecOutput {
pub fn new() -> Self {
Self(Vec::new())
}
}
impl SerOutput for VecOutput {
type Output = Vec<u8>;
#[inline(always)]
fn try_extend(&mut self, data: &[u8]) -> core::result::Result<(), ()> {
self.0.extend_from_slice(data);
Ok(())
}
#[inline(always)]
fn try_push(&mut self, data: u8) -> core::result::Result<(), ()> {
self.0.push(data);
Ok(())
}
fn release(self) -> core::result::Result<Self::Output, ()> {
Ok(self.0)
}
}
impl Index<usize> for VecOutput {
type Output = u8;
fn index(&self, idx: usize) -> &u8 {
&self.0[idx]
}
}
impl IndexMut<usize> for VecOutput {
fn index_mut(&mut self, idx: usize) -> &mut u8 {
&mut self.0[idx]
}
}