Skip to content

Instantly share code, notes, and snippets.

@jamesmunns
Last active February 20, 2023 03:14
Show Gist options
  • Save jamesmunns/de99d22c7dbfd0e47f8ac87e0c1a8872 to your computer and use it in GitHub Desktop.
Save jamesmunns/de99d22c7dbfd0e47f8ac87e0c1a8872 to your computer and use it in GitHub Desktop.
use postcard::de_flavors::Flavor;
use serde::{Serialize, Deserialize};
struct Interner<'i> {
input: Vec<u8>,
intern: &'i mut [u8],
}
impl<'i> Flavor<'i> for Interner<'i> {
type Remainder = ();
type Source = ();
fn pop(&mut self) -> postcard::Result<u8> {
self.input.pop().ok_or(postcard::Error::DeserializeUnexpectedEnd)
}
fn try_take_n(&mut self, ct: usize) -> postcard::Result<&'i [u8]> {
if ct > self.intern.len() {
// this is the wrong error
return Err(postcard::Error::DeserializeUnexpectedEnd)
}
let remain = core::mem::take(&mut self.intern);
let (now, later) = remain.split_at_mut(ct);
self.intern = later;
now.iter_mut().try_for_each(|d| {
*d = self.pop()?;
Ok(())
})?;
Ok(now)
}
fn finalize(self) -> postcard::Result<Self::Remainder> {
Ok(())
}
}
#[derive(Debug, Serialize, Deserialize)]
struct Demo<'a> {
a: u8,
b: u32,
c: &'a str,
d: &'a [u8],
}
fn main() {
let alpha = Demo { a: 10, b: 20, c: "cr1901", d: b"demo" };
let beta = postcard::to_stdvec(&alpha).unwrap();
// reverse to make "pop" easier
let delta = beta.into_iter().rev().collect::<Vec<_>>();
let mut gamma = [0u8; 100];
let mut deser = postcard::Deserializer::from_flavor(Interner { input: delta, intern: &mut gamma });
let t = Demo::<'_>::deserialize(&mut deser).unwrap();
println!("{:?}", t);
drop(deser);
println!("{:?}", t);
// Can't do this, we need `gamma` to live longer than `t`.
//
// drop(gamma);
// println!("{:?}", t);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment