Fix tuple struct encoding in serde (#549)

This commit is contained in:
Lena Hellström 2022-06-04 14:56:20 +02:00 committed by GitHub
parent e7d2292dc2
commit f979383adb
7 changed files with 96 additions and 18 deletions

View File

@ -42,6 +42,7 @@ criterion = "0.3"
rand = "0.8"
uuid = { version = "0.8", features = ["serde"] }
chrono = { version = "0.4", features = ["serde"] }
glam = { version="0.20.5", features=["serde"] }
[[bench]]
name = "varint"

View File

@ -1,6 +1,7 @@
#[test]
fn test() {
super::test_same((1,));
super::test_same(TupleS(2.0, 3.0, 4.0));
super::test_same(Option::<u32>::Some(5));
super::test_same(Option::<u32>::None);
super::test_same(Result::<u32, u8>::Ok(5));
@ -8,3 +9,9 @@ fn test() {
super::test_same(std::net::Ipv4Addr::LOCALHOST);
super::test_same(std::net::Ipv6Addr::LOCALHOST);
}
#[derive(
bincode_2::Encode, bincode_2::Decode, serde::Serialize, serde::Deserialize, Debug, PartialEq,
)]
#[bincode(crate = "bincode_2")]
struct TupleS(f32, f32, f32);

View File

@ -234,11 +234,10 @@ where
}
fn serialize_tuple_struct(
mut self,
self,
_name: &'static str,
len: usize,
_len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
len.encode(&mut self.enc)?;
Ok(Compound { enc: self.enc })
}

View File

@ -23,3 +23,6 @@ mod issue_500;
#[path = "issues/issue_523.rs"]
mod issue_523;
#[path = "issues/issue_547.rs"]
mod issue_547;

24
tests/issues/issue_547.rs Normal file
View File

@ -0,0 +1,24 @@
#![cfg(all(feature = "serde", feature = "std"))]
use glam::vec3;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Instance {
position: glam::Vec3,
}
#[test]
fn test() {
let instance = Instance {
position: vec3(2.0, 2.0, 2.0),
};
let m = bincode::serde::encode_to_vec(&instance, bincode::config::standard()).unwrap();
let instance2: Instance = bincode::serde::decode_from_slice(&m, bincode::config::standard())
.unwrap()
.0;
assert_eq!(instance, instance2);
}

View File

@ -10,28 +10,44 @@ pub struct SerdeRoundtrip {
pub a: u32,
#[serde(skip)]
pub b: u32,
pub c: TupleS,
}
#[derive(Serialize, Deserialize, bincode::Encode, bincode::Decode, PartialEq, Debug)]
pub struct TupleS(f32, f32, f32);
#[test]
fn test_serde_round_trip() {
// validate serde attribute working
let json = serde_json::to_string(&SerdeRoundtrip { a: 5, b: 5 }).unwrap();
assert_eq!("{\"a\":5}", json);
let json = serde_json::to_string(&SerdeRoundtrip {
a: 5,
b: 5,
c: TupleS(2.0, 3.0, 4.0),
})
.unwrap();
assert_eq!("{\"a\":5,\"c\":[2.0,3.0,4.0]}", json);
let result: SerdeRoundtrip = serde_json::from_str(&json).unwrap();
assert_eq!(result.a, 5);
assert_eq!(result.b, 0);
// validate bincode working
let bytes =
bincode::encode_to_vec(SerdeRoundtrip { a: 15, b: 15 }, bincode::config::standard())
.unwrap();
assert_eq!(bytes, &[15, 15]);
let bytes = bincode::serde::encode_to_vec(
SerdeRoundtrip {
a: 15,
b: 15,
c: TupleS(2.0, 3.0, 4.0),
},
bincode::config::standard(),
)
.unwrap();
assert_eq!(bytes, &[15, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 128, 64]);
let (result, len): (SerdeRoundtrip, usize) =
bincode::decode_from_slice(&bytes, bincode::config::standard()).unwrap();
bincode::serde::decode_from_slice(&bytes, bincode::config::standard()).unwrap();
assert_eq!(result.a, 15);
assert_eq!(result.b, 15);
assert_eq!(len, 2);
assert_eq!(result.b, 0); // remember: b is skipped
assert_eq!(result.c, TupleS(2.0, 3.0, 4.0));
assert_eq!(len, 13);
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]

View File

@ -27,12 +27,35 @@ where
);
assert_eq!(len, decoded_len);
#[cfg(all(feature = "serde", feature = "alloc"))]
// skip_fixed_array_length is not supposed on serde
#[cfg(feature = "serde")]
the_same_with_config_serde(element, config, cmp)
}
#[cfg(feature = "serde")]
fn the_same_with_config_serde<V, C, CMP>(element: &V, config: C, cmp: CMP)
where
V: TheSameTrait,
C: bincode::config::Config,
CMP: Fn(&V, &V) -> bool,
{
use bincode::error::EncodeError;
let mut buffer = [0u8; 2048];
let len = bincode::serde::encode_into_slice(&element, &mut buffer, config);
let decoded = bincode::serde::decode_from_slice(&mut buffer, config);
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();
let len = len.unwrap();
let (decoded, decoded_len): (V, usize) = decoded.unwrap();
println!(
"{:?} ({}): {:?} ({:?})",
element,
core::any::type_name::<V>(),
&buffer[..len],
core::any::type_name::<C>()
);
assert!(
cmp(&element, &decoded),
"Comparison failed\nDecoded: {:?}\nExpected: {:?}\nBytes: {:?}",
@ -40,7 +63,12 @@ where
element,
&buffer[..len],
);
assert_eq!(decoded_len, len);
assert_eq!(len, decoded_len);
} else {
match len.unwrap_err() {
EncodeError::Serde(bincode::serde::EncodeError::SkipFixedArrayLengthNotSupported) => {}
err => panic!("Unexpected error: {:?}", err),
}
}
}