Skip to content

Instantly share code, notes, and snippets.

@jorendorff
Forked from anonymous/playground.rs
Created October 11, 2017 19:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jorendorff/82a193e4c88fb369cf50002968f5ea7d to your computer and use it in GitHub Desktop.
Save jorendorff/82a193e4c88fb369cf50002968f5ea7d to your computer and use it in GitHub Desktop.
Rust code shared from the playground
use std::fmt::Debug;
struct Reader<'a> {
buf: &'a [u8],
}
impl<'a> Reader<'a> {
fn read<'b>(&'b mut self, len: usize) -> Result<&'a [u8], ()> {
if len <= self.buf.len() {
let (read, remains) = self.buf.split_at(len);
self.buf = remains;
Ok(read)
} else {
Err(())
}
}
}
trait Unpack<'a>: Sized {
fn unpack<'b>(reader: &'b mut Reader<'a>) -> Result<Self, ()>;
}
#[derive(Debug)]
struct A(Vec<u8>);
impl<'a> Unpack<'a> for A {
fn unpack<'b>(reader: &'b mut Reader<'a>) -> Result<Self, ()> {
Ok(A(reader.read(2)?.to_vec()))
}
}
#[derive(Debug)]
struct B<'a>(&'a [u8]);
// B<'b> values can be unpacked from a Reader<'a>, but only if 'a outlives 'b.
impl<'a, 'b> Unpack<'a> for B<'b> where 'a: 'b {
fn unpack(reader: &mut Reader<'a>) -> Result<Self, ()> {
Ok(B(reader.read(2)?))
}
}
use std::marker::PhantomData;
struct UnpackDebugImp<'r>(fn(&mut Reader<'r>) -> Result<String, ()>);
impl<'r> UnpackDebugImp<'r> {
fn new<T>() -> Self
where
T: Unpack<'r> + Debug,
{
UnpackDebugImp(|r| T::unpack(r).map(|t| format!("{:?}", t)))
}
fn call(&self, r: &mut Reader<'r>) -> Result<String, ()> {
(self.0)(r)
}
}
fn main() {
let mut r = Reader { buf: b"abcdef" };
// this works:
println!("{:?}", UnpackDebugImp::new::<A>().call(&mut r));
// this doesn't:
println!("{:?}", UnpackDebugImp::new::<B>().call(&mut r));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment