use bytes::{Buf, BufMut}; use varint; #[derive(Fail, Debug, Copy, Clone, Eq, PartialEq)] #[fail(display = "unexpected end of buffer")] pub struct UnexpectedEnd; pub type Result = ::std::result::Result; pub trait Value: Sized { fn decode(buf: &mut B) -> Result; fn encode(&self, buf: &mut B); } impl Value for u8 { fn decode(buf: &mut B) -> Result { if buf.remaining() < 1 { return Err(UnexpectedEnd); } Ok(buf.get_u8()) } fn encode(&self, buf: &mut B) { buf.put_u8(*self); } } impl Value for u16 { fn decode(buf: &mut B) -> Result { if buf.remaining() < 2 { return Err(UnexpectedEnd); } Ok(buf.get_u16_be()) } fn encode(&self, buf: &mut B) { buf.put_u16_be(*self); } } impl Value for u32 { fn decode(buf: &mut B) -> Result { if buf.remaining() < 4 { return Err(UnexpectedEnd); } Ok(buf.get_u32_be()) } fn encode(&self, buf: &mut B) { buf.put_u32_be(*self); } } impl Value for u64 { fn decode(buf: &mut B) -> Result { if buf.remaining() < 8 { return Err(UnexpectedEnd); } Ok(buf.get_u64_be()) } fn encode(&self, buf: &mut B) { buf.put_u64_be(*self); } } pub trait BufExt { fn get(&mut self) -> Result; fn get_var(&mut self) -> Result; } impl BufExt for T { fn get(&mut self) -> Result { U::decode(self) } fn get_var(&mut self) -> Result { varint::read(self).ok_or(UnexpectedEnd) } } pub trait BufMutExt { fn write(&mut self, x: T); fn write_var(&mut self, x: u64); } impl BufMutExt for T { fn write(&mut self, x: U) { x.encode(self); } fn write_var(&mut self, x: u64) { varint::write(x, self).unwrap() } }