From e414cabd33c4a3c21c24df2063672058632b5bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lena=20Hellstr=C3=B6m?= Date: Mon, 20 Sep 2021 16:35:36 +0200 Subject: [PATCH] Add derive for Decodeable --- derive/src/derive_struct.rs | 29 ++++++++++++++++++++++++++++- src/de/mod.rs | 26 ++++++++++++++++++++------ tests/derive.rs | 21 ++++++++++++++++++++- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/derive/src/derive_struct.rs b/derive/src/derive_struct.rs index 1668657..5680850 100644 --- a/derive/src/derive_struct.rs +++ b/derive/src/derive_struct.rs @@ -63,6 +63,33 @@ impl DeriveStruct { } pub fn to_decodable(self) -> Result { - unimplemented!() + let DeriveStruct { + name, + generics, + fields, + } = self; + + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let fields = fields + .into_iter() + .map(|field| { + quote! { + #field: bincode::de::Decodable::decode(&mut decoder)?, + } + }) + .collect::>(); + + let result = quote! { + impl #impl_generics bincode::de::Decodable for #name #ty_generics #where_clause { + fn decode(mut decoder: D) -> Result<#name #ty_generics, bincode::error::DecodeError> { + Ok(#name { + #(#fields)* + }) + } + + } + }; + Ok(result.into()) } } diff --git a/src/de/mod.rs b/src/de/mod.rs index 0295e58..8ee5567 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -1,7 +1,7 @@ use core::marker::PhantomData; use crate::{ - config::{Config, Endian}, + config::{Config, Endian, IntEncoding}, error::DecodeError, }; use read::Reader; @@ -33,12 +33,26 @@ impl<'de, R: Reader<'de>, C: Config> Decoder { impl<'a, 'de, R: Reader<'de>, C: Config> Decode for &'a mut Decoder { fn decode_u32(&mut self) -> Result { - let mut bytes = [0u8; 4]; + Ok(match C::INT_ENCODING { + IntEncoding::Variable => crate::varint::varint_decode_u32(&mut self.reader, C::ENDIAN)?, + IntEncoding::Fixed => { + let mut bytes = [0u8; 4]; - self.reader.read(bytes.as_mut())?; - Ok(match C::ENDIAN { - Endian::Little => u32::from_le_bytes(bytes), - Endian::Big => u32::from_be_bytes(bytes), + self.reader.read(bytes.as_mut())?; + match C::ENDIAN { + Endian::Little => u32::from_le_bytes(bytes), + Endian::Big => u32::from_be_bytes(bytes), + } + } }) } } + +impl<'a, T> Decode for &'a mut T +where + T: Decode, +{ + fn decode_u32(&mut self) -> Result { + T::decode_u32(self) + } +} diff --git a/tests/derive.rs b/tests/derive.rs index 155925b..27c23f3 100644 --- a/tests/derive.rs +++ b/tests/derive.rs @@ -1,4 +1,4 @@ -use bincode::enc::Encodeable; +use bincode::{de::Decodable, enc::Encodeable}; #[derive(bincode::Encodable, PartialEq, Debug)] pub struct Test { @@ -7,6 +7,13 @@ pub struct Test { c: u8, } +#[derive(bincode::Decodable, PartialEq, Debug, Eq)] +pub struct Test2 { + a: T, + b: u32, + c: u32, +} + #[test] fn test_encodable() { let start = Test { @@ -19,3 +26,15 @@ fn test_encodable() { assert_eq!(bytes_written, 3); assert_eq!(&slice[..bytes_written], &[10, 10, 20]); } + +#[test] +fn test_decodable() { + let start = Test2 { + a: 5u32, + b: 10u32, + c: 1024u32, + }; + let mut slice = [5, 10, 251, 0, 4]; + let result: Test2 = bincode::decode(&mut slice).unwrap(); + assert_eq!(result, start); +}