Added support for slices, str, fixed size arrays. Added lifetime to Decode trait
This commit is contained in:
parent
ffb565c405
commit
9c7fb85e0e
|
|
@ -13,4 +13,4 @@ proc-macro2 = "1.0"
|
||||||
[dependencies.syn]
|
[dependencies.syn]
|
||||||
version = "1.0.74"
|
version = "1.0.74"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["parsing", "derive", "proc-macro", "printing"]
|
features = ["parsing", "derive", "proc-macro", "printing", "clone-impls"]
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
|
use proc_macro2::Span;
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
use proc_macro2::TokenStream as TokenStream2;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
|
use syn::GenericParam;
|
||||||
|
use syn::Lifetime;
|
||||||
|
use syn::LifetimeDef;
|
||||||
use syn::{spanned::Spanned, Fields, Generics, Ident, Index, Variant};
|
use syn::{spanned::Spanned, Fields, Generics, Ident, Index, Variant};
|
||||||
pub struct DeriveEnum {
|
pub struct DeriveEnum {
|
||||||
name: Ident,
|
name: Ident,
|
||||||
|
|
@ -63,7 +67,34 @@ impl DeriveEnum {
|
||||||
variants,
|
variants,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
let (mut impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
|
// check if we don't already have a '__de lifetime
|
||||||
|
let mut should_insert_lifetime = true;
|
||||||
|
|
||||||
|
for param in &generics.params {
|
||||||
|
if let GenericParam::Lifetime(lt) = param {
|
||||||
|
if lt.lifetime.ident == "__de" {
|
||||||
|
should_insert_lifetime = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we don't have a '__de lifetime, insert it
|
||||||
|
let mut generics_with_decode_lifetime;
|
||||||
|
if should_insert_lifetime {
|
||||||
|
generics_with_decode_lifetime = generics.clone();
|
||||||
|
generics_with_decode_lifetime
|
||||||
|
.params
|
||||||
|
.push(GenericParam::Lifetime(LifetimeDef::new(Lifetime::new(
|
||||||
|
"'__de",
|
||||||
|
Span::call_site(),
|
||||||
|
))));
|
||||||
|
|
||||||
|
impl_generics = generics_with_decode_lifetime.split_for_impl().0;
|
||||||
|
}
|
||||||
|
|
||||||
let max_variant = (variants.len() - 1) as u32;
|
let max_variant = (variants.len() - 1) as u32;
|
||||||
let match_arms = variants.iter().enumerate().map(|(index, variant)| {
|
let match_arms = variants.iter().enumerate().map(|(index, variant)| {
|
||||||
let index = index as u32;
|
let index = index as u32;
|
||||||
|
|
@ -79,8 +110,8 @@ impl DeriveEnum {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let result = quote! {
|
let result = quote! {
|
||||||
impl #impl_generics bincode::de::Decodable for #name #ty_generics #where_clause {
|
impl #impl_generics bincode::de::Decodable<'__de> for #name #ty_generics #where_clause {
|
||||||
fn decode<D: bincode::de::Decode>(mut decoder: D) -> Result<#name #ty_generics, bincode::error::DecodeError> {
|
fn decode<D: bincode::de::Decode<'__de>>(mut decoder: D) -> Result<#name #ty_generics, bincode::error::DecodeError> {
|
||||||
let i = decoder.decode_u32()?;
|
let i = decoder.decode_u32()?;
|
||||||
Ok(match i {
|
Ok(match i {
|
||||||
#(#match_arms)*
|
#(#match_arms)*
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::TokenStream as TokenStream2;
|
use proc_macro2::{Span, TokenStream as TokenStream2};
|
||||||
use quote::{quote, ToTokens};
|
use quote::{quote, ToTokens};
|
||||||
use syn::{Generics, Ident, Index};
|
use syn::{GenericParam, Generics, Ident, Index, Lifetime, LifetimeDef};
|
||||||
|
|
||||||
pub struct DeriveStruct {
|
pub struct DeriveStruct {
|
||||||
name: Ident,
|
name: Ident,
|
||||||
|
|
@ -70,7 +70,33 @@ impl DeriveStruct {
|
||||||
fields,
|
fields,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
let (mut impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||||
|
|
||||||
|
// check if we don't already have a '__de lifetime
|
||||||
|
let mut should_insert_lifetime = true;
|
||||||
|
|
||||||
|
for param in &generics.params {
|
||||||
|
if let GenericParam::Lifetime(lt) = param {
|
||||||
|
if lt.lifetime.ident == "__de" {
|
||||||
|
should_insert_lifetime = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we don't have a '__de lifetime, insert it
|
||||||
|
let mut generics_with_decode_lifetime;
|
||||||
|
if should_insert_lifetime {
|
||||||
|
generics_with_decode_lifetime = generics.clone();
|
||||||
|
generics_with_decode_lifetime
|
||||||
|
.params
|
||||||
|
.push(GenericParam::Lifetime(LifetimeDef::new(Lifetime::new(
|
||||||
|
"'__de",
|
||||||
|
Span::call_site(),
|
||||||
|
))));
|
||||||
|
|
||||||
|
impl_generics = generics_with_decode_lifetime.split_for_impl().0;
|
||||||
|
}
|
||||||
|
|
||||||
let fields = fields
|
let fields = fields
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -82,8 +108,8 @@ impl DeriveStruct {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let result = quote! {
|
let result = quote! {
|
||||||
impl #impl_generics bincode::de::Decodable for #name #ty_generics #where_clause {
|
impl #impl_generics bincode::de::Decodable< '__de > for #name #ty_generics #where_clause {
|
||||||
fn decode<D: bincode::de::Decode>(mut decoder: D) -> Result<#name #ty_generics, bincode::error::DecodeError> {
|
fn decode<D: bincode::de::Decode< '__de >>(mut decoder: D) -> Result<Self, bincode::error::DecodeError> {
|
||||||
Ok(#name {
|
Ok(#name {
|
||||||
#(#fields)*
|
#(#fields)*
|
||||||
})
|
})
|
||||||
|
|
@ -91,6 +117,7 @@ impl DeriveStruct {
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(result.into())
|
Ok(result.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
37
docs/spec.md
37
docs/spec.md
|
|
@ -90,6 +90,8 @@ assert_eq!(encoded.as_slice(), &[
|
||||||
|
|
||||||
Collections are encoded with their length value first, following by each entry of the collection. The length value is based on your `IntEncoding`.
|
Collections are encoded with their length value first, following by each entry of the collection. The length value is based on your `IntEncoding`.
|
||||||
|
|
||||||
|
**note**: fixed array length do not have their `len` encoded. See [Arrays](#arrays)
|
||||||
|
|
||||||
```rs
|
```rs
|
||||||
let list = vec![
|
let list = vec![
|
||||||
0u8,
|
0u8,
|
||||||
|
|
@ -121,3 +123,38 @@ assert_eq!(encoded.as_slice(), &[
|
||||||
b'H', b'e', b'l', b'l', b'o'
|
b'H', b'e', b'l', b'l', b'o'
|
||||||
]);
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Arrays
|
||||||
|
|
||||||
|
Arrays are encoded *without* a length.
|
||||||
|
|
||||||
|
```rs
|
||||||
|
let arr: [u8; 5] = [10, 20, 30, 40, 50];
|
||||||
|
let encoded = bincode::encode_to_vec(&list).unwrap();
|
||||||
|
assert_eq!(encoded.as_slice(), &[10, 20, 30, 40 50]);
|
||||||
|
```
|
||||||
|
|
||||||
|
This applies to any type `T` that implements `Encodabl`/`Decodabl`
|
||||||
|
|
||||||
|
```rs
|
||||||
|
#[derive(bincode::Encodabl)]
|
||||||
|
struct Foo {
|
||||||
|
first: u8,
|
||||||
|
second: u8
|
||||||
|
};
|
||||||
|
|
||||||
|
let arr: [Foo; 2] = [
|
||||||
|
Foo {
|
||||||
|
first: 10,
|
||||||
|
second: 20,
|
||||||
|
},
|
||||||
|
Foo {
|
||||||
|
first: 30,
|
||||||
|
second: 40,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let encoded = bincode::encode_to_vec(&list).unwrap();
|
||||||
|
assert_eq!(encoded.as_slice(), &[10, 20, 30, 40]);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ impl<'de, R: Reader<'de>, C: Config> Decoder<R, C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'de, R: Reader<'de>, C: Config> Decode for &'a mut Decoder<R, C> {
|
impl<'a, 'de, R: Reader<'de>, C: Config> Decode<'de> for &'a mut Decoder<R, C> {
|
||||||
fn decode_u8(&mut self) -> Result<u8, DecodeError> {
|
fn decode_u8(&mut self) -> Result<u8, DecodeError> {
|
||||||
let mut bytes = [0u8; 1];
|
let mut bytes = [0u8; 1];
|
||||||
self.reader.read(&mut bytes)?;
|
self.reader.read(&mut bytes)?;
|
||||||
|
|
@ -198,8 +198,8 @@ impl<'a, 'de, R: Reader<'de>, C: Config> Decode for &'a mut Decoder<R, C> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_slice(&mut self, slice: &mut [u8]) -> Result<(), DecodeError> {
|
fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError> {
|
||||||
self.reader.read(slice)
|
self.reader.forward_read(len, |s| s)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError> {
|
fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError> {
|
||||||
|
|
|
||||||
|
|
@ -1,99 +1,119 @@
|
||||||
use super::{Decodable, Decode};
|
use super::{Decodable, Decode};
|
||||||
use crate::error::DecodeError;
|
use crate::error::DecodeError;
|
||||||
|
|
||||||
impl Decodable for u8 {
|
impl<'de> Decodable<'de> for u8 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_u8()
|
decoder.decode_u8()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for u16 {
|
impl<'de> Decodable<'de> for u16 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_u16()
|
decoder.decode_u16()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for u32 {
|
impl<'de> Decodable<'de> for u32 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_u32()
|
decoder.decode_u32()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for u64 {
|
impl<'de> Decodable<'de> for u64 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_u64()
|
decoder.decode_u64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for u128 {
|
impl<'de> Decodable<'de> for u128 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_u128()
|
decoder.decode_u128()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for usize {
|
impl<'de> Decodable<'de> for usize {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_usize()
|
decoder.decode_usize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for i8 {
|
impl<'de> Decodable<'de> for i8 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_i8()
|
decoder.decode_i8()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for i16 {
|
impl<'de> Decodable<'de> for i16 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_i16()
|
decoder.decode_i16()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for i32 {
|
impl<'de> Decodable<'de> for i32 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_i32()
|
decoder.decode_i32()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for i64 {
|
impl<'de> Decodable<'de> for i64 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_i64()
|
decoder.decode_i64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for i128 {
|
impl<'de> Decodable<'de> for i128 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_i128()
|
decoder.decode_i128()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for isize {
|
impl<'de> Decodable<'de> for isize {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_isize()
|
decoder.decode_isize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for f32 {
|
impl<'de> Decodable<'de> for f32 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_f32()
|
decoder.decode_f32()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Decodable for f64 {
|
impl<'de> Decodable<'de> for f64 {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_f64()
|
decoder.decode_f64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> Decodable for [u8; N] {
|
impl<'de> Decodable<'de> for &'de [u8] {
|
||||||
fn decode<D: Decode>(mut decoder: D) -> Result<Self, DecodeError> {
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
|
let len = usize::decode(&mut decoder)?;
|
||||||
|
decoder.decode_slice(len)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Decodable<'de> for &'de str {
|
||||||
|
fn decode<D: Decode<'de>>(decoder: D) -> Result<Self, DecodeError> {
|
||||||
|
let slice: &[u8] = Decodable::decode(decoder)?;
|
||||||
|
core::str::from_utf8(slice).map_err(DecodeError::Utf8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, const N: usize> Decodable<'de> for [u8; N] {
|
||||||
|
fn decode<D: Decode<'de>>(mut decoder: D) -> Result<Self, DecodeError> {
|
||||||
decoder.decode_array()
|
decoder.decode_array()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Decode for &'a mut T
|
impl<'de, T> Decodable<'de> for core::marker::PhantomData<T> {
|
||||||
|
fn decode<D: Decode<'de>>(_: D) -> Result<Self, DecodeError> {
|
||||||
|
Ok(core::marker::PhantomData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'de, T> Decode<'de> for &'a mut T
|
||||||
where
|
where
|
||||||
T: Decode,
|
T: Decode<'de>,
|
||||||
{
|
{
|
||||||
fn decode_u8(&mut self) -> Result<u8, DecodeError> {
|
fn decode_u8(&mut self) -> Result<u8, DecodeError> {
|
||||||
T::decode_u8(self)
|
T::decode_u8(self)
|
||||||
|
|
@ -151,8 +171,8 @@ where
|
||||||
T::decode_f64(self)
|
T::decode_f64(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_slice(&mut self, slice: &mut [u8]) -> Result<(), DecodeError> {
|
fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError> {
|
||||||
T::decode_slice(self, slice)
|
T::decode_slice(self, len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError> {
|
fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError> {
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@ mod impls;
|
||||||
pub mod read;
|
pub mod read;
|
||||||
pub use self::decoder::Decoder;
|
pub use self::decoder::Decoder;
|
||||||
|
|
||||||
pub trait Decodable: Sized {
|
pub trait Decodable<'de>: Sized {
|
||||||
fn decode<D: Decode>(decoder: D) -> Result<Self, DecodeError>;
|
fn decode<D: Decode<'de>>(decoder: D) -> Result<Self, DecodeError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Decode {
|
pub trait Decode<'de> {
|
||||||
fn decode_u8(&mut self) -> Result<u8, DecodeError>;
|
fn decode_u8(&mut self) -> Result<u8, DecodeError>;
|
||||||
fn decode_u16(&mut self) -> Result<u16, DecodeError>;
|
fn decode_u16(&mut self) -> Result<u16, DecodeError>;
|
||||||
fn decode_u32(&mut self) -> Result<u32, DecodeError>;
|
fn decode_u32(&mut self) -> Result<u32, DecodeError>;
|
||||||
|
|
@ -27,6 +27,6 @@ pub trait Decode {
|
||||||
|
|
||||||
fn decode_f32(&mut self) -> Result<f32, DecodeError>;
|
fn decode_f32(&mut self) -> Result<f32, DecodeError>;
|
||||||
fn decode_f64(&mut self) -> Result<f64, DecodeError>;
|
fn decode_f64(&mut self) -> Result<f64, DecodeError>;
|
||||||
fn decode_slice(&mut self, slice: &mut [u8]) -> Result<(), DecodeError>;
|
fn decode_slice(&mut self, len: usize) -> Result<&'de [u8], DecodeError>;
|
||||||
fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError>;
|
fn decode_array<const N: usize>(&mut self) -> Result<[u8; N], DecodeError>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,11 @@ impl<'a, W: Writer, C: Config> Encode for &'a mut Encoder<W, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_slice(&mut self, val: &[u8]) -> Result<(), EncodeError> {
|
fn encode_slice(&mut self, val: &[u8]) -> Result<(), EncodeError> {
|
||||||
|
self.encode_usize(val.len())?;
|
||||||
self.writer.write(val)
|
self.writer.write(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn encode_array<const N: usize>(&mut self, val: [u8; N]) -> Result<(), EncodeError> {
|
||||||
|
self.writer.write(&val)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,18 @@ impl Encodeable for &'_ [u8] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encodeable for &'_ str {
|
||||||
|
fn encode<E: Encode>(&self, mut encoder: E) -> Result<(), EncodeError> {
|
||||||
|
encoder.encode_slice(self.as_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> Encodeable for [u8; N] {
|
||||||
|
fn encode<E: Encode>(&self, mut encoder: E) -> Result<(), EncodeError> {
|
||||||
|
encoder.encode_array(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, T> Encode for &'a mut T
|
impl<'a, T> Encode for &'a mut T
|
||||||
where
|
where
|
||||||
T: Encode,
|
T: Encode,
|
||||||
|
|
@ -142,4 +154,7 @@ where
|
||||||
fn encode_slice(&mut self, val: &[u8]) -> Result<(), EncodeError> {
|
fn encode_slice(&mut self, val: &[u8]) -> Result<(), EncodeError> {
|
||||||
T::encode_slice(self, val)
|
T::encode_slice(self, val)
|
||||||
}
|
}
|
||||||
|
fn encode_array<const N: usize>(&mut self, val: [u8; N]) -> Result<(), EncodeError> {
|
||||||
|
T::encode_array(self, val)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,4 +29,5 @@ pub trait Encode {
|
||||||
fn encode_f32(&mut self, val: f32) -> Result<(), EncodeError>;
|
fn encode_f32(&mut self, val: f32) -> Result<(), EncodeError>;
|
||||||
fn encode_f64(&mut self, val: f64) -> Result<(), EncodeError>;
|
fn encode_f64(&mut self, val: f64) -> Result<(), EncodeError>;
|
||||||
fn encode_slice(&mut self, val: &[u8]) -> Result<(), EncodeError>;
|
fn encode_slice(&mut self, val: &[u8]) -> Result<(), EncodeError>;
|
||||||
|
fn encode_array<const N: usize>(&mut self, val: [u8; N]) -> Result<(), EncodeError>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ pub enum DecodeError {
|
||||||
max: u32,
|
max: u32,
|
||||||
found: u32,
|
found: u32,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Utf8(core::str::Utf8Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
|
|
||||||
|
|
@ -43,12 +43,14 @@ pub fn encode_into_slice_with_config<E: enc::Encodeable, C: Config>(
|
||||||
Ok(encoder.into_writer().bytes_written())
|
Ok(encoder.into_writer().bytes_written())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode<D: de::Decodable>(src: &mut [u8]) -> Result<D, error::DecodeError> {
|
pub fn decode<'__de, D: de::Decodable<'__de>>(
|
||||||
|
src: &'__de mut [u8],
|
||||||
|
) -> Result<D, error::DecodeError> {
|
||||||
decode_with_config(src, config::Default)
|
decode_with_config(src, config::Default)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode_with_config<D: de::Decodable, C: Config>(
|
pub fn decode_with_config<'__de, D: de::Decodable<'__de>, C: Config>(
|
||||||
src: &mut [u8],
|
src: &'__de mut [u8],
|
||||||
_config: C,
|
_config: C,
|
||||||
) -> Result<D, error::DecodeError> {
|
) -> Result<D, error::DecodeError> {
|
||||||
let reader = de::read::SliceReader::new(src);
|
let reader = de::read::SliceReader::new(src);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use bincode::{de::Decodable, enc::Encodeable};
|
use bincode::{de::Decodable, enc::Encodeable};
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
#[derive(bincode::Encodable, PartialEq, Debug)]
|
#[derive(bincode::Encodable, PartialEq, Debug)]
|
||||||
pub struct Test<T: Encodeable> {
|
pub struct Test<T: Encodeable> {
|
||||||
|
|
@ -8,10 +9,11 @@ pub struct Test<T: Encodeable> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(bincode::Decodable, PartialEq, Debug, Eq)]
|
#[derive(bincode::Decodable, PartialEq, Debug, Eq)]
|
||||||
pub struct Test2<T: Decodable> {
|
pub struct Test2<'__de, T: Decodable<'__de>> {
|
||||||
a: T,
|
a: T,
|
||||||
b: u32,
|
b: u32,
|
||||||
c: u32,
|
c: u32,
|
||||||
|
pd: PhantomData<&'__de ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(bincode::Encodable, bincode::Decodable, PartialEq, Debug, Eq)]
|
#[derive(bincode::Encodable, bincode::Decodable, PartialEq, Debug, Eq)]
|
||||||
|
|
@ -43,6 +45,7 @@ fn test_decodable() {
|
||||||
a: 5u32,
|
a: 5u32,
|
||||||
b: 10u32,
|
b: 10u32,
|
||||||
c: 1024u32,
|
c: 1024u32,
|
||||||
|
pd: PhantomData,
|
||||||
};
|
};
|
||||||
let mut slice = [5, 10, 251, 0, 4];
|
let mut slice = [5, 10, 251, 0, 4];
|
||||||
let result: Test2<u32> = bincode::decode(&mut slice).unwrap();
|
let result: Test2<u32> = bincode::decode(&mut slice).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,12 @@ use core::fmt::Debug;
|
||||||
|
|
||||||
fn the_same_with_config<V, C>(element: V, config: C)
|
fn the_same_with_config<V, C>(element: V, config: C)
|
||||||
where
|
where
|
||||||
V: bincode::enc::Encodeable + bincode::de::Decodable + PartialEq + Debug + Clone + 'static,
|
V: bincode::enc::Encodeable
|
||||||
|
+ for<'de> bincode::de::Decodable<'de>
|
||||||
|
+ PartialEq
|
||||||
|
+ Debug
|
||||||
|
+ Clone
|
||||||
|
+ 'static,
|
||||||
C: Config,
|
C: Config,
|
||||||
{
|
{
|
||||||
let mut buffer = [0u8; 32];
|
let mut buffer = [0u8; 32];
|
||||||
|
|
@ -16,7 +21,12 @@ where
|
||||||
}
|
}
|
||||||
fn the_same<V>(element: V)
|
fn the_same<V>(element: V)
|
||||||
where
|
where
|
||||||
V: bincode::enc::Encodeable + bincode::de::Decodable + PartialEq + Debug + Clone + 'static,
|
V: bincode::enc::Encodeable
|
||||||
|
+ for<'de> bincode::de::Decodable<'de>
|
||||||
|
+ PartialEq
|
||||||
|
+ Debug
|
||||||
|
+ Clone
|
||||||
|
+ 'static,
|
||||||
{
|
{
|
||||||
the_same_with_config(
|
the_same_with_config(
|
||||||
element.clone(),
|
element.clone(),
|
||||||
|
|
@ -61,3 +71,39 @@ fn test_numbers() {
|
||||||
the_same(5.0f32);
|
the_same(5.0f32);
|
||||||
the_same(5.0f64);
|
the_same(5.0f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_slice() {
|
||||||
|
let mut buffer = [0u8; 32];
|
||||||
|
let input: &[u8] = &[1, 2, 3, 4, 5, 6, 7];
|
||||||
|
bincode::encode_into_slice(input, &mut buffer).unwrap();
|
||||||
|
assert_eq!(&buffer[..8], &[7, 1, 2, 3, 4, 5, 6, 7]);
|
||||||
|
|
||||||
|
let output: &[u8] = bincode::decode(&mut buffer[..8]).unwrap();
|
||||||
|
assert_eq!(input, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_str() {
|
||||||
|
let mut buffer = [0u8; 32];
|
||||||
|
let input: &str = "Hello world";
|
||||||
|
bincode::encode_into_slice(input, &mut buffer).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
&buffer[..12],
|
||||||
|
&[11, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
|
||||||
|
);
|
||||||
|
|
||||||
|
let output: &str = bincode::decode(&mut buffer[..12]).unwrap();
|
||||||
|
assert_eq!(input, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_array() {
|
||||||
|
let mut buffer = [0u8; 32];
|
||||||
|
let input: [u8; 10] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
|
||||||
|
bincode::encode_into_slice(input, &mut buffer).unwrap();
|
||||||
|
assert_eq!(&buffer[..10], &[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]);
|
||||||
|
|
||||||
|
let output: [u8; 10] = bincode::decode(&mut buffer[..10]).unwrap();
|
||||||
|
assert_eq!(input, output);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue