use std::cell::Cell;
use std::rc::Rc;
pub struct PagableVecFlavor {
vec: Vec<u8>,
}
impl PagableVecFlavor {
pub fn new() -> Self {
Self { vec: Vec::new() }
}
#[inline]
pub fn position(&self) -> usize {
self.vec.len()
}
#[inline]
pub fn write_at(&mut self, pos: usize, bytes: &[u8]) {
self.vec[pos..pos + bytes.len()].copy_from_slice(bytes);
}
}
impl Default for PagableVecFlavor {
fn default() -> Self {
Self::new()
}
}
impl postcard::ser_flavors::Flavor for PagableVecFlavor {
type Output = Vec<u8>;
#[inline(always)]
fn try_extend(&mut self, data: &[u8]) -> postcard::Result<()> {
self.vec.extend_from_slice(data);
Ok(())
}
#[inline(always)]
fn try_push(&mut self, data: u8) -> postcard::Result<()> {
self.vec.push(data);
Ok(())
}
fn finalize(self) -> postcard::Result<Self::Output> {
Ok(self.vec)
}
}
#[derive(Clone, Default)]
pub struct SharedPosition(Rc<Cell<usize>>);
impl SharedPosition {
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn get(&self) -> usize {
self.0.get()
}
#[inline]
pub fn set(&self, pos: usize) {
self.0.set(pos);
}
}
pub struct PagableSlice<'de> {
bytes: &'de [u8],
pos: SharedPosition,
}
impl<'de> PagableSlice<'de> {
pub fn new(bytes: &'de [u8], pos: SharedPosition) -> Self {
Self { bytes, pos }
}
}
impl<'de> postcard::de_flavors::Flavor<'de> for PagableSlice<'de> {
type Remainder = &'de [u8];
type Source = &'de [u8];
#[inline]
fn pop(&mut self) -> postcard::Result<u8> {
let p = self.pos.get();
if p < self.bytes.len() {
let b = self.bytes[p];
self.pos.set(p + 1);
Ok(b)
} else {
Err(postcard::Error::DeserializeUnexpectedEnd)
}
}
#[inline]
fn size_hint(&self) -> Option<usize> {
Some(self.bytes.len() - self.pos.get())
}
#[inline]
fn try_take_n(&mut self, ct: usize) -> postcard::Result<&'de [u8]> {
let p = self.pos.get();
let end = p + ct;
if end <= self.bytes.len() {
let slice = &self.bytes[p..end];
self.pos.set(end);
Ok(slice)
} else {
Err(postcard::Error::DeserializeUnexpectedEnd)
}
}
fn try_take_n_temp<'a>(&'a mut self, ct: usize) -> postcard::Result<&'a [u8]>
where
'de: 'a,
{
let p = self.pos.get();
let end = p + ct;
if end <= self.bytes.len() {
let slice = &self.bytes[p..end];
self.pos.set(end);
Ok(slice)
} else {
Err(postcard::Error::DeserializeUnexpectedEnd)
}
}
fn finalize(self) -> postcard::Result<Self::Remainder> {
Ok(&self.bytes[self.pos.get()..])
}
}