You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pubtraitDecodable{typeDecoder:Decoder<Item = Self>;/// Decodes `Self` by reading from a buffered reader.#[cfg(any(feature = "std", feature = "core"))]fnfrom_reader<R:BufRead>(mutreader:R) -> Result<Self,IoError<Self::Error>>{letmut deserializer = Self::Decoder::default();whileletOk(buf) = reader.fill_buf()? {if buf.is_empty(){break;}let consumed = deserializer.put_bytes(buf).map_err(IoError::Decode)?;
reader.consume(consumed);if consumed < buf.len(){break;}}
deserializer.end().map_err(Into::into)}/// Decodes `Self` from given slice containing *full* data.////// The slice must **not** be partial - use `Decoder` API to handle partial slices./// Returns the number of bytes consumed as the second field of the tuple on success.fnfrom_slice(bytes:&[u8]) -> Result<(Self::Item,usize),DecodeError<Self::Error>{letmut decoder = Self::Decoder::default();let consumed = decoder.put_bytes(bytes).map_err(DecodeError::Decode)?;let item = decoder.end()?;Ok((item, consumed))}}pubtraitDecoder:Default{typeItem;typeError;// perhaps we should require our own error trait?/// Add these bytes into deserializer state.////// Returns the number of consumed bytes on success, error if data was corrupted./// If the returned number is less than `buf.len()` then this decoder finished decoding and `end()` should be called./// It will no longer accept any bytes.////// ## Panics////// The function should panic if `bytes` is empty.fnput_bytes(&mutself,bytes:&[u8]) -> Result<usize,Self::Error>;/// Finishes decoding the item.////// Returns decoded item or `UnexpectedEndError` if decoding didn't finish.fnend(self) -> Result<Self::Item,UnexpectedEndError>;}// not entirely correct macro, just to give you an ideamacro_rules! fixed_size_decodable {($type:ty, $decoder:ident, $len:expr, $conversion_method:ident) => {pubstruct $decoder {// could be MaybeUninit in the future, this should be well-contained// or model it with an enum
buf:[u8; $len],
len:usize,}impl $crate::Decoderfor $decoder {fn put_bytes(&mutself, bytes:&[u8]) -> Result<usize,Self::Error> {let dst = &mutself.buf[self.len..];let to_copy = dst.len().min(bytes.len());
dst[..to_copy].copy_from_slice(&bytes[..to_copy]);self.len += to_copy;Ok(to_copy)}fn end(self) -> Result<Self,UnexpectedEndError> {ifself.len == $len {Ok($type::$conversion_method(self.buf))} else {Err(UnexpectedEndError::new(self.len, $len))}}}}}fixed_size_decodable!(u32,U32Decoder,4, from_be_bytes);
I also envision MinLenDecodable and ExactLenDecodable traits to simplify decoding for some types where they'd only have to implement conversions from byte arrays.
I just realized push-based consensus decoding could solve a bunch of issues:
asyncdeserializationWritetraitDesign draft (owned decoding only):
I also envision
MinLenDecodableandExactLenDecodabletraits to simplify decoding for some types where they'd only have to implement conversions from byte arrays.