Fix/issue 500 (#503)

* Fixed an issue where serde would decode a sequence with an u32 instead of a usize

* Added serde to the `the_same` test for roundtrips, fixed several issues.

* Fixed backwards compatibility for result, ipv4addr and ipv6addr

* Processed feedback
This commit is contained in:
Trangar 2022-02-07 16:52:15 +01:00 committed by GitHub
parent da94b7aaf9
commit 58dc788dfa
17 changed files with 285 additions and 43 deletions

View File

@ -3,6 +3,7 @@
use ::rand::Rng; use ::rand::Rng;
use bincode_1::Options; use bincode_1::Options;
mod misc;
mod rand; mod rand;
mod sway; mod sway;
@ -20,6 +21,8 @@ where
// This is what bincode 1 serializes to. This will be our comparison value. // This is what bincode 1 serializes to. This will be our comparison value.
let encoded = bincode_1_options.serialize(t).unwrap(); let encoded = bincode_1_options.serialize(t).unwrap();
println!("Encoded {:?} as {:?}", t, encoded);
// Test bincode 2 encode // Test bincode 2 encode
let bincode_2_output = bincode_2::encode_to_vec(t, bincode_2_config).unwrap(); let bincode_2_output = bincode_2::encode_to_vec(t, bincode_2_config).unwrap();
assert_eq!(encoded, bincode_2_output, "{:?} serializes differently", t); assert_eq!(encoded, bincode_2_output, "{:?} serializes differently", t);

10
compatibility/src/misc.rs Normal file
View File

@ -0,0 +1,10 @@
#[test]
fn test() {
super::test_same((1,));
super::test_same(Option::<u32>::Some(5));
super::test_same(Option::<u32>::None);
super::test_same(Result::<u32, u8>::Ok(5));
super::test_same(Result::<u32, u8>::Err(5));
super::test_same(std::net::Ipv4Addr::LOCALHOST);
super::test_same(std::net::Ipv6Addr::LOCALHOST);
}

View File

@ -162,6 +162,8 @@ impl<E, I, A, L> Configuration<E, I, A, L> {
} }
/// Skip writing the length of fixed size arrays (`[u8; N]`) before writing the array /// Skip writing the length of fixed size arrays (`[u8; N]`) before writing the array
///
/// **NOTE:** This is not supported if you're using the `bincode::serde::*` functions, the `#[bincode(with_serde)]` attribute, or the `Compat` struct.
pub const fn skip_fixed_array_length(self) -> Configuration<E, I, SkipFixedArrayLength, L> { pub const fn skip_fixed_array_length(self) -> Configuration<E, I, SkipFixedArrayLength, L> {
generate() generate()
} }

View File

@ -512,7 +512,7 @@ where
U: Decode, U: Decode,
{ {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> { fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
let is_ok = u8::decode(decoder)?; let is_ok = u32::decode(decoder)?;
match is_ok { match is_ok {
0 => { 0 => {
let t = T::decode(decoder)?; let t = T::decode(decoder)?;

View File

@ -387,11 +387,11 @@ where
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> { fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
match self { match self {
Ok(val) => { Ok(val) => {
0u8.encode(encoder)?; 0u32.encode(encoder)?;
val.encode(encoder) val.encode(encoder)
} }
Err(err) => { Err(err) => {
1u8.encode(encoder)?; 1u32.encode(encoder)?;
err.encode(encoder) err.encode(encoder)
} }
} }

View File

@ -268,25 +268,29 @@ impl Decode for IpAddr {
impl Encode for Ipv4Addr { impl Encode for Ipv4Addr {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> { fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
self.octets().encode(encoder) encoder.writer().write(&self.octets())
} }
} }
impl Decode for Ipv4Addr { impl Decode for Ipv4Addr {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> { fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
Ok(Self::from(<[u8; 4]>::decode(decoder)?)) let mut buff = [0u8; 4];
decoder.reader().read(&mut buff)?;
Ok(Self::from(buff))
} }
} }
impl Encode for Ipv6Addr { impl Encode for Ipv6Addr {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> { fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
self.octets().encode(encoder) encoder.writer().write(&self.octets())
} }
} }
impl Decode for Ipv6Addr { impl Decode for Ipv6Addr {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> { fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
Ok(Self::from(<[u8; 16]>::decode(decoder)?)) let mut buff = [0u8; 16];
decoder.reader().read(&mut buff)?;
Ok(Self::from(buff))
} }
} }

View File

@ -13,6 +13,9 @@ where
T: Deserialize<'de>, T: Deserialize<'de>,
C: Config, C: Config,
{ {
if C::SKIP_FIXED_ARRAY_LENGTH {
return Err(SerdeDecodeError::SkipFixedArrayLengthNotSupported.into());
}
let reader = crate::de::read::SliceReader::new(slice); let reader = crate::de::read::SliceReader::new(slice);
let mut decoder = crate::de::DecoderImpl::new(reader, config); let mut decoder = crate::de::DecoderImpl::new(reader, config);
let serde_decoder = SerdeDecoder { let serde_decoder = SerdeDecoder {
@ -72,6 +75,15 @@ impl<'a, 'de, DE: BorrowDecoder<'de>> Deserializer<'de> for SerdeDecoder<'a, 'de
visitor.visit_i64(Decode::decode(&mut self.de)?) visitor.visit_i64(Decode::decode(&mut self.de)?)
} }
serde_incl::serde_if_integer128! {
fn deserialize_i128<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde_incl::de::Visitor<'de>,
{
visitor.visit_i128(Decode::decode(&mut self.de)?)
}
}
fn deserialize_u8<V>(mut self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize_u8<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where where
V: serde_incl::de::Visitor<'de>, V: serde_incl::de::Visitor<'de>,
@ -100,6 +112,15 @@ impl<'a, 'de, DE: BorrowDecoder<'de>> Deserializer<'de> for SerdeDecoder<'a, 'de
visitor.visit_u64(Decode::decode(&mut self.de)?) visitor.visit_u64(Decode::decode(&mut self.de)?)
} }
serde_incl::serde_if_integer128! {
fn deserialize_u128<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde_incl::de::Visitor<'de>,
{
visitor.visit_u128(Decode::decode(&mut self.de)?)
}
}
fn deserialize_f32<V>(mut self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize_f32<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where where
V: serde_incl::de::Visitor<'de>, V: serde_incl::de::Visitor<'de>,
@ -214,8 +235,8 @@ impl<'a, 'de, DE: BorrowDecoder<'de>> Deserializer<'de> for SerdeDecoder<'a, 'de
where where
V: serde_incl::de::Visitor<'de>, V: serde_incl::de::Visitor<'de>,
{ {
let len = u32::decode(&mut self.de)?; let len = usize::decode(&mut self.de)?;
self.deserialize_tuple(len as usize, visitor) self.deserialize_tuple(len, visitor)
} }
fn deserialize_tuple<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error> fn deserialize_tuple<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
@ -367,6 +388,10 @@ impl<'a, 'de, DE: BorrowDecoder<'de>> Deserializer<'de> for SerdeDecoder<'a, 'de
{ {
Err(SerdeDecodeError::IgnoredAnyNotSupported.into()) Err(SerdeDecodeError::IgnoredAnyNotSupported.into())
} }
fn is_human_readable(&self) -> bool {
false
}
} }
impl<'de, 'a, DE: BorrowDecoder<'de>> EnumAccess<'de> for SerdeDecoder<'a, 'de, DE> { impl<'de, 'a, DE: BorrowDecoder<'de>> EnumAccess<'de> for SerdeDecoder<'a, 'de, DE> {

View File

@ -16,6 +16,9 @@ where
T: DeserializeOwned, T: DeserializeOwned,
C: Config, C: Config,
{ {
if C::SKIP_FIXED_ARRAY_LENGTH {
return Err(SerdeDecodeError::SkipFixedArrayLengthNotSupported.into());
}
let reader = crate::de::read::SliceReader::new(slice); let reader = crate::de::read::SliceReader::new(slice);
let mut decoder = crate::de::DecoderImpl::new(reader, config); let mut decoder = crate::de::DecoderImpl::new(reader, config);
let serde_decoder = SerdeDecoder { de: &mut decoder }; let serde_decoder = SerdeDecoder { de: &mut decoder };
@ -31,6 +34,9 @@ pub fn decode_from_std_read<D: DeserializeOwned, C: Config, R: std::io::Read>(
src: &mut R, src: &mut R,
config: C, config: C,
) -> Result<D, DecodeError> { ) -> Result<D, DecodeError> {
if C::SKIP_FIXED_ARRAY_LENGTH {
return Err(SerdeDecodeError::SkipFixedArrayLengthNotSupported.into());
}
let reader = crate::IoReader::new(src); let reader = crate::IoReader::new(src);
let mut decoder = crate::de::DecoderImpl::new(reader, config); let mut decoder = crate::de::DecoderImpl::new(reader, config);
let serde_decoder = SerdeDecoder { de: &mut decoder }; let serde_decoder = SerdeDecoder { de: &mut decoder };
@ -46,6 +52,9 @@ pub fn decode_from_reader<D: DeserializeOwned, R: Reader, C: Config>(
reader: R, reader: R,
config: C, config: C,
) -> Result<D, DecodeError> { ) -> Result<D, DecodeError> {
if C::SKIP_FIXED_ARRAY_LENGTH {
return Err(SerdeDecodeError::SkipFixedArrayLengthNotSupported.into());
}
let mut decoder = crate::de::DecoderImpl::<_, C>::new(reader, config); let mut decoder = crate::de::DecoderImpl::<_, C>::new(reader, config);
let serde_decoder = SerdeDecoder { de: &mut decoder }; let serde_decoder = SerdeDecoder { de: &mut decoder };
D::deserialize(serde_decoder) D::deserialize(serde_decoder)
@ -100,6 +109,15 @@ impl<'a, 'de, DE: Decoder> Deserializer<'de> for SerdeDecoder<'a, DE> {
visitor.visit_i64(Decode::decode(&mut self.de)?) visitor.visit_i64(Decode::decode(&mut self.de)?)
} }
serde_incl::serde_if_integer128! {
fn deserialize_i128<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde_incl::de::Visitor<'de>,
{
visitor.visit_i128(Decode::decode(&mut self.de)?)
}
}
fn deserialize_u8<V>(mut self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize_u8<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where where
V: serde_incl::de::Visitor<'de>, V: serde_incl::de::Visitor<'de>,
@ -128,6 +146,15 @@ impl<'a, 'de, DE: Decoder> Deserializer<'de> for SerdeDecoder<'a, DE> {
visitor.visit_u64(Decode::decode(&mut self.de)?) visitor.visit_u64(Decode::decode(&mut self.de)?)
} }
serde_incl::serde_if_integer128! {
fn deserialize_u128<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde_incl::de::Visitor<'de>,
{
visitor.visit_u128(Decode::decode(&mut self.de)?)
}
}
fn deserialize_f32<V>(mut self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize_f32<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where where
V: serde_incl::de::Visitor<'de>, V: serde_incl::de::Visitor<'de>,
@ -257,8 +284,8 @@ impl<'a, 'de, DE: Decoder> Deserializer<'de> for SerdeDecoder<'a, DE> {
where where
V: serde_incl::de::Visitor<'de>, V: serde_incl::de::Visitor<'de>,
{ {
let len = u32::decode(&mut self.de)?; let len = usize::decode(&mut self.de)?;
self.deserialize_tuple(len as usize, visitor) self.deserialize_tuple(len, visitor)
} }
fn deserialize_tuple<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error> fn deserialize_tuple<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
@ -407,6 +434,10 @@ impl<'a, 'de, DE: Decoder> Deserializer<'de> for SerdeDecoder<'a, DE> {
{ {
Err(SerdeDecodeError::IgnoredAnyNotSupported.into()) Err(SerdeDecodeError::IgnoredAnyNotSupported.into())
} }
fn is_human_readable(&self) -> bool {
false
}
} }
impl<'de, 'a, DE: Decoder> EnumAccess<'de> for SerdeDecoder<'a, DE> { impl<'de, 'a, DE: Decoder> EnumAccess<'de> for SerdeDecoder<'a, DE> {

View File

@ -89,6 +89,9 @@ pub enum DecodeError {
/// Serde tried decoding a borrowed value from an owned reader. Use `serde_decode_borrowed_from_*` instead /// Serde tried decoding a borrowed value from an owned reader. Use `serde_decode_borrowed_from_*` instead
CannotBorrowOwnedData, CannotBorrowOwnedData,
/// Serde does not support skipping fixed array lengths
SkipFixedArrayLengthNotSupported,
/// Could not allocate data like `String` and `Vec<u8>` /// Could not allocate data like `String` and `Vec<u8>`
#[cfg(not(feature = "alloc"))] #[cfg(not(feature = "alloc"))]
CannotAllocate, CannotAllocate,
@ -136,6 +139,9 @@ pub enum EncodeError {
/// Serde provided bincode with a sequence without a length, which is not supported in bincode /// Serde provided bincode with a sequence without a length, which is not supported in bincode
SequenceMustHaveLength, SequenceMustHaveLength,
/// Serde does not support skipping fixed array lengths
SkipFixedArrayLengthNotSupported,
/// [Serializer::collect_str] got called but bincode was unable to allocate memory. /// [Serializer::collect_str] got called but bincode was unable to allocate memory.
#[cfg(not(feature = "alloc"))] #[cfg(not(feature = "alloc"))]
CannotCollectStr, CannotCollectStr,

View File

@ -16,6 +16,9 @@ where
T: Serialize, T: Serialize,
C: Config, C: Config,
{ {
if C::SKIP_FIXED_ARRAY_LENGTH {
return Err(SerdeEncodeError::SkipFixedArrayLengthNotSupported.into());
}
let mut encoder = crate::enc::EncoderImpl::new(crate::VecWriter::default(), config); let mut encoder = crate::enc::EncoderImpl::new(crate::VecWriter::default(), config);
let serializer = SerdeEncoder { enc: &mut encoder }; let serializer = SerdeEncoder { enc: &mut encoder };
t.serialize(serializer)?; t.serialize(serializer)?;
@ -28,6 +31,9 @@ where
T: Serialize, T: Serialize,
C: Config, C: Config,
{ {
if C::SKIP_FIXED_ARRAY_LENGTH {
return Err(SerdeEncodeError::SkipFixedArrayLengthNotSupported.into());
}
let mut encoder = let mut encoder =
crate::enc::EncoderImpl::new(crate::enc::write::SliceWriter::new(slice), config); crate::enc::EncoderImpl::new(crate::enc::write::SliceWriter::new(slice), config);
let serializer = SerdeEncoder { enc: &mut encoder }; let serializer = SerdeEncoder { enc: &mut encoder };
@ -45,6 +51,9 @@ pub fn encode_into_writer<E: Serialize, W: Writer, C: Config>(
writer: W, writer: W,
config: C, config: C,
) -> Result<(), EncodeError> { ) -> Result<(), EncodeError> {
if C::SKIP_FIXED_ARRAY_LENGTH {
return Err(SerdeEncodeError::SkipFixedArrayLengthNotSupported.into());
}
let mut encoder = crate::enc::EncoderImpl::<_, C>::new(writer, config); let mut encoder = crate::enc::EncoderImpl::<_, C>::new(writer, config);
let serializer = SerdeEncoder { enc: &mut encoder }; let serializer = SerdeEncoder { enc: &mut encoder };
val.serialize(serializer)?; val.serialize(serializer)?;
@ -62,6 +71,9 @@ pub fn encode_into_std_write<E: Serialize, C: Config, W: std::io::Write>(
dst: &mut W, dst: &mut W,
config: C, config: C,
) -> Result<usize, EncodeError> { ) -> Result<usize, EncodeError> {
if C::SKIP_FIXED_ARRAY_LENGTH {
return Err(SerdeEncodeError::SkipFixedArrayLengthNotSupported.into());
}
let writer = crate::IoWriter::new(dst); let writer = crate::IoWriter::new(dst);
let mut encoder = crate::enc::EncoderImpl::<_, C>::new(writer, config); let mut encoder = crate::enc::EncoderImpl::<_, C>::new(writer, config);
let serializer = SerdeEncoder { enc: &mut encoder }; let serializer = SerdeEncoder { enc: &mut encoder };
@ -109,6 +121,12 @@ where
v.encode(self.enc) v.encode(self.enc)
} }
serde_incl::serde_if_integer128! {
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
v.encode(self.enc)
}
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> { fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
v.encode(self.enc) v.encode(self.enc)
} }
@ -125,6 +143,12 @@ where
v.encode(self.enc) v.encode(self.enc)
} }
serde_incl::serde_if_integer128! {
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
v.encode(self.enc)
}
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> { fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
v.encode(self.enc) v.encode(self.enc)
} }
@ -205,8 +229,7 @@ where
Ok(Compound { enc: self.enc }) Ok(Compound { enc: self.enc })
} }
fn serialize_tuple(mut self, len: usize) -> Result<Self::SerializeTuple, Self::Error> { fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
len.encode(&mut self.enc)?;
Ok(self) Ok(self)
} }
@ -262,6 +285,10 @@ where
{ {
Err(SerdeEncodeError::CannotCollectStr.into()) Err(SerdeEncodeError::CannotCollectStr.into())
} }
fn is_human_readable(&self) -> bool {
false
}
} }
type Compound<'a, ENC> = SerdeEncoder<'a, ENC>; type Compound<'a, ENC> = SerdeEncoder<'a, ENC>;

View File

@ -6,8 +6,9 @@ mod utils;
use alloc::borrow::Cow; use alloc::borrow::Cow;
use alloc::collections::*; use alloc::collections::*;
#[cfg(not(feature = "serde"))]
use alloc::rc::Rc; use alloc::rc::Rc;
#[cfg(feature = "atomic")] #[cfg(all(feature = "atomic", not(feature = "serde")))]
use alloc::sync::Arc; use alloc::sync::Arc;
use utils::{the_same, the_same_with_comparer}; use utils::{the_same, the_same_with_comparer};
@ -58,8 +59,11 @@ fn test_alloc_commons() {
the_same(Box::<[u32]>::from(vec![1, 2, 3, 4, 5])); the_same(Box::<[u32]>::from(vec![1, 2, 3, 4, 5]));
the_same(Cow::<u32>::Owned(5)); the_same(Cow::<u32>::Owned(5));
the_same(Cow::<u32>::Borrowed(&5)); the_same(Cow::<u32>::Borrowed(&5));
// Serde doesn't support Rc<u32>
#[cfg(not(feature = "serde"))]
the_same(Rc::<u32>::new(5)); the_same(Rc::<u32>::new(5));
#[cfg(feature = "atomic")] // serde doesn't support Arc<u32>
#[cfg(all(feature = "atomic", not(feature = "serde")))]
the_same(Arc::<u32>::new(5)); the_same(Arc::<u32>::new(5));
the_same_with_comparer( the_same_with_comparer(
{ {

View File

@ -48,6 +48,7 @@ fn test_numbers() {
// arrays // arrays
#[rustfmt::skip] #[rustfmt::skip]
#[cfg(not(feature = "serde"))] // serde doesn't support arrays this big
the_same([ the_same([
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
@ -217,6 +218,21 @@ fn test_array() {
bincode::decode_from_slice(&mut buffer[..10], bincode::config::standard()).unwrap(); bincode::decode_from_slice(&mut buffer[..10], bincode::config::standard()).unwrap();
assert_eq!(input, output); assert_eq!(input, output);
assert_eq!(len, 10); assert_eq!(len, 10);
let mut buffer = [0u8; 32];
let input: [u8; 1] = [1];
let config = bincode::config::standard()
.write_fixed_array_length()
.with_fixed_int_encoding()
.with_little_endian();
let len = bincode::encode_into_slice(input, &mut buffer, config).unwrap();
assert_eq!(len, 9);
assert_eq!(&buffer[..9], &[1, 0, 0, 0, 0, 0, 0, 0, 1]);
let (output, len): (&[u8], usize) =
bincode::decode_from_slice(&mut buffer[..9], config).unwrap();
assert_eq!(input, output);
assert_eq!(len, 9);
} }
#[test] #[test]

View File

@ -17,3 +17,6 @@ mod issue_474;
#[path = "issues/issue_498.rs"] #[path = "issues/issue_498.rs"]
mod issue_498; mod issue_498;
#[path = "issues/issue_500.rs"]
mod issue_500;

View File

@ -62,7 +62,7 @@ impl MemCache {
where where
T: Send + Sync + serde_incl::Serialize, T: Send + Sync + serde_incl::Serialize,
{ {
let config = bincode::config::standard(); let config = bincode::config::standard().write_fixed_array_length();
let mut guard = self.cache.write().unwrap(); let mut guard = self.cache.write().unwrap();
let encoded = bincode::serde::encode_to_vec(&cache_data, config)?; let encoded = bincode::serde::encode_to_vec(&cache_data, config)?;
@ -76,7 +76,7 @@ impl MemCache {
where where
T: Send + Sync + DeserializeOwned, T: Send + Sync + DeserializeOwned,
{ {
let config = bincode::config::standard(); let config = bincode::config::standard().write_fixed_array_length();
let guard = self.cache.read().unwrap(); let guard = self.cache.read().unwrap();
let cache_item = guard.get(key).unwrap(); let cache_item = guard.get(key).unwrap();
let (decoded, _len): (T, usize) = let (decoded, _len): (T, usize) =

37
tests/issues/issue_500.rs Normal file
View File

@ -0,0 +1,37 @@
#![cfg(all(feature = "serde", feature = "derive", feature = "std"))]
extern crate std;
type NodeId = u64;
use std::collections::BTreeSet;
#[derive(
bincode::Encode,
bincode::Decode,
serde_derive::Serialize,
serde_derive::Deserialize,
Debug,
PartialEq,
)]
#[serde(crate = "serde_incl")]
pub struct Membership {
/// learners set
learners: BTreeSet<NodeId>,
}
#[test]
fn test() {
let mut start = Membership {
learners: BTreeSet::new(),
};
start.learners.insert(1);
let config = bincode::config::legacy();
let encoded = bincode::encode_to_vec(&start, config).unwrap();
std::dbg!(&encoded);
let decoded: Membership = bincode::serde::decode_from_slice(&encoded, config)
.unwrap()
.0;
assert_eq!(start, decoded);
}

View File

@ -24,12 +24,17 @@ fn test_serde_round_trip() {
assert_eq!(result.b, 0); assert_eq!(result.b, 0);
// validate bincode working // validate bincode working
let bytes = let bytes = bincode::encode_to_vec(
bincode::encode_to_vec(SerdeRoundtrip { a: 15, b: 15 }, bincode::config::standard()) SerdeRoundtrip { a: 15, b: 15 },
bincode::config::standard().write_fixed_array_length(),
)
.unwrap(); .unwrap();
assert_eq!(bytes, &[15, 15]); assert_eq!(bytes, &[15, 15]);
let (result, len): (SerdeRoundtrip, usize) = let (result, len): (SerdeRoundtrip, usize) = bincode::decode_from_slice(
bincode::decode_from_slice(&bytes, bincode::config::standard()).unwrap(); &bytes,
bincode::config::standard().write_fixed_array_length(),
)
.unwrap();
assert_eq!(result.a, 15); assert_eq!(result.a, 15);
assert_eq!(result.b, 15); assert_eq!(result.b, 15);
assert_eq!(len, 2); assert_eq!(len, 2);
@ -61,17 +66,28 @@ fn test_serialize_deserialize_borrowed_data() {
]; ];
let mut result = [0u8; 20]; let mut result = [0u8; 20];
let len = bincode::serde::encode_into_slice(&input, &mut result, bincode::config::standard()) let len = bincode::serde::encode_into_slice(
&input,
&mut result,
bincode::config::standard().write_fixed_array_length(),
)
.unwrap(); .unwrap();
let result = &result[..len]; let result = &result[..len];
assert_eq!(result, expected); assert_eq!(result, expected);
let result = bincode::serde::encode_to_vec(&input, bincode::config::standard()).unwrap(); let result = bincode::serde::encode_to_vec(
&input,
bincode::config::standard().write_fixed_array_length(),
)
.unwrap();
assert_eq!(result, expected); assert_eq!(result, expected);
let output: SerdeWithBorrowedData = let output: SerdeWithBorrowedData = bincode::serde::decode_borrowed_from_slice(
bincode::serde::decode_borrowed_from_slice(&result, bincode::config::standard()).unwrap(); &result,
bincode::config::standard().write_fixed_array_length(),
)
.unwrap();
assert_eq!( assert_eq!(
SerdeWithBorrowedData { SerdeWithBorrowedData {
b: 0, // remember: b is skipped b: 0, // remember: b is skipped
@ -107,17 +123,28 @@ fn test_serialize_deserialize_owned_data() {
]; ];
let mut result = [0u8; 20]; let mut result = [0u8; 20];
let len = bincode::serde::encode_into_slice(&input, &mut result, bincode::config::standard()) let len = bincode::serde::encode_into_slice(
&input,
&mut result,
bincode::config::standard().write_fixed_array_length(),
)
.unwrap(); .unwrap();
let result = &result[..len]; let result = &result[..len];
assert_eq!(result, expected); assert_eq!(result, expected);
let result = bincode::serde::encode_to_vec(&input, bincode::config::standard()).unwrap(); let result = bincode::serde::encode_to_vec(
&input,
bincode::config::standard().write_fixed_array_length(),
)
.unwrap();
assert_eq!(result, expected); assert_eq!(result, expected);
let (output, len): (SerdeWithOwnedData, usize) = let (output, len): (SerdeWithOwnedData, usize) = bincode::serde::decode_from_slice(
bincode::serde::decode_from_slice(&result, bincode::config::standard()).unwrap(); &result,
bincode::config::standard().write_fixed_array_length(),
)
.unwrap();
assert_eq!( assert_eq!(
SerdeWithOwnedData { SerdeWithOwnedData {
b: 0, // remember: b is skipped b: 0, // remember: b is skipped
@ -161,12 +188,19 @@ mod derive {
T: bincode::Encode + bincode::Decode + PartialEq + core::fmt::Debug, T: bincode::Encode + bincode::Decode + PartialEq + core::fmt::Debug,
{ {
let mut slice = [0u8; 100]; let mut slice = [0u8; 100];
let len = bincode::encode_into_slice(&start, &mut slice, bincode::config::standard()) let len = bincode::encode_into_slice(
&start,
&mut slice,
bincode::config::standard().write_fixed_array_length(),
)
.unwrap(); .unwrap();
assert_eq!(len, expected_len); assert_eq!(len, expected_len);
let slice = &slice[..len]; let slice = &slice[..len];
let (result, len): (T, usize) = let (result, len): (T, usize) = bincode::decode_from_slice(
bincode::decode_from_slice(&slice, bincode::config::standard()).unwrap(); &slice,
bincode::config::standard().write_fixed_array_length(),
)
.unwrap();
assert_eq!(start, result); assert_eq!(start, result);
assert_eq!(len, expected_len); assert_eq!(len, expected_len);

View File

@ -2,15 +2,16 @@ use core::fmt::Debug;
fn the_same_with_config<V, C, CMP>(element: &V, config: C, cmp: CMP) fn the_same_with_config<V, C, CMP>(element: &V, config: C, cmp: CMP)
where where
V: bincode::Encode + bincode::Decode + Debug + 'static, V: TheSameTrait,
C: bincode::config::Config, C: bincode::config::Config,
CMP: Fn(&V, &V) -> bool, CMP: Fn(&V, &V) -> bool,
{ {
let mut buffer = [0u8; 2048]; let mut buffer = [0u8; 2048];
let len = bincode::encode_into_slice(&element, &mut buffer, config).unwrap(); let len = bincode::encode_into_slice(&element, &mut buffer, config).unwrap();
println!( println!(
"{:?}: {:?} ({:?})", "{:?} ({}): {:?} ({:?})",
element, element,
core::any::type_name::<V>(),
&buffer[..len], &buffer[..len],
core::any::type_name::<C>() core::any::type_name::<C>()
); );
@ -25,11 +26,27 @@ where
&buffer[..len], &buffer[..len],
); );
assert_eq!(len, decoded_len); assert_eq!(len, decoded_len);
#[cfg(feature = "serde")]
// skip_fixed_array_length is not supposed on serde
if !C::SKIP_FIXED_ARRAY_LENGTH {
let encoded = bincode::serde::encode_to_vec(&element, config).unwrap();
assert_eq!(&buffer[..len], &encoded);
let (decoded, decoded_len) = bincode::serde::decode_from_slice(&encoded, config).unwrap();
assert!(
cmp(&element, &decoded),
"Comparison failed\nDecoded: {:?}\nExpected: {:?}\nBytes: {:?}",
decoded,
element,
&buffer[..len],
);
assert_eq!(decoded_len, len);
}
} }
pub fn the_same_with_comparer<V, CMP>(element: V, cmp: CMP) pub fn the_same_with_comparer<V, CMP>(element: V, cmp: CMP)
where where
V: bincode::Encode + bincode::Decode + Debug + 'static, V: TheSameTrait,
CMP: Fn(&V, &V) -> bool, CMP: Fn(&V, &V) -> bool,
{ {
// A matrix of each different config option possible // A matrix of each different config option possible
@ -99,10 +116,33 @@ where
); );
} }
#[allow(dead_code)] // This is not used in every test #[cfg(feature = "serde")]
pub fn the_same<V>(element: V) pub trait TheSameTrait:
where bincode::Encode
V: bincode::Encode + bincode::Decode + PartialEq + Debug + 'static, + bincode::Decode
+ serde_incl::de::DeserializeOwned
+ serde_incl::Serialize
+ Debug
+ 'static
{ {
}
#[cfg(feature = "serde")]
impl<T> TheSameTrait for T where
T: bincode::Encode
+ bincode::Decode
+ serde_incl::de::DeserializeOwned
+ serde_incl::Serialize
+ Debug
+ 'static
{
}
#[cfg(not(feature = "serde"))]
pub trait TheSameTrait: bincode::Encode + bincode::Decode + Debug + 'static {}
#[cfg(not(feature = "serde"))]
impl<T> TheSameTrait for T where T: bincode::Encode + bincode::Decode + Debug + 'static {}
#[allow(dead_code)] // This is not used in every test
pub fn the_same<V: TheSameTrait + PartialEq>(element: V) {
the_same_with_comparer(element, |a, b| a == b); the_same_with_comparer(element, |a, b| a == b);
} }