Fix tuple struct encoding in serde (#549)
This commit is contained in:
parent
e7d2292dc2
commit
f979383adb
|
|
@ -42,6 +42,7 @@ criterion = "0.3"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
uuid = { version = "0.8", features = ["serde"] }
|
uuid = { version = "0.8", features = ["serde"] }
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
glam = { version="0.20.5", features=["serde"] }
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "varint"
|
name = "varint"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test() {
|
||||||
super::test_same((1,));
|
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>::Some(5));
|
||||||
super::test_same(Option::<u32>::None);
|
super::test_same(Option::<u32>::None);
|
||||||
super::test_same(Result::<u32, u8>::Ok(5));
|
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::Ipv4Addr::LOCALHOST);
|
||||||
super::test_same(std::net::Ipv6Addr::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);
|
||||||
|
|
|
||||||
|
|
@ -234,11 +234,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_tuple_struct(
|
fn serialize_tuple_struct(
|
||||||
mut self,
|
self,
|
||||||
_name: &'static str,
|
_name: &'static str,
|
||||||
len: usize,
|
_len: usize,
|
||||||
) -> Result<Self::SerializeTupleStruct, Self::Error> {
|
) -> Result<Self::SerializeTupleStruct, Self::Error> {
|
||||||
len.encode(&mut self.enc)?;
|
|
||||||
Ok(Compound { enc: self.enc })
|
Ok(Compound { enc: self.enc })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,3 +23,6 @@ mod issue_500;
|
||||||
|
|
||||||
#[path = "issues/issue_523.rs"]
|
#[path = "issues/issue_523.rs"]
|
||||||
mod issue_523;
|
mod issue_523;
|
||||||
|
|
||||||
|
#[path = "issues/issue_547.rs"]
|
||||||
|
mod issue_547;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -10,28 +10,44 @@ pub struct SerdeRoundtrip {
|
||||||
pub a: u32,
|
pub a: u32,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub b: u32,
|
pub b: u32,
|
||||||
|
pub c: TupleS,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, bincode::Encode, bincode::Decode, PartialEq, Debug)]
|
||||||
|
pub struct TupleS(f32, f32, f32);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serde_round_trip() {
|
fn test_serde_round_trip() {
|
||||||
// validate serde attribute working
|
// validate serde attribute working
|
||||||
let json = serde_json::to_string(&SerdeRoundtrip { a: 5, b: 5 }).unwrap();
|
let json = serde_json::to_string(&SerdeRoundtrip {
|
||||||
assert_eq!("{\"a\":5}", json);
|
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();
|
let result: SerdeRoundtrip = serde_json::from_str(&json).unwrap();
|
||||||
assert_eq!(result.a, 5);
|
assert_eq!(result.a, 5);
|
||||||
assert_eq!(result.b, 0);
|
assert_eq!(result.b, 0);
|
||||||
|
|
||||||
// validate bincode working
|
// validate bincode working
|
||||||
let bytes =
|
let bytes = bincode::serde::encode_to_vec(
|
||||||
bincode::encode_to_vec(SerdeRoundtrip { a: 15, b: 15 }, bincode::config::standard())
|
SerdeRoundtrip {
|
||||||
.unwrap();
|
a: 15,
|
||||||
assert_eq!(bytes, &[15, 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) =
|
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.a, 15);
|
||||||
assert_eq!(result.b, 15);
|
assert_eq!(result.b, 0); // remember: b is skipped
|
||||||
assert_eq!(len, 2);
|
assert_eq!(result.c, TupleS(2.0, 3.0, 4.0));
|
||||||
|
assert_eq!(len, 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,35 @@ where
|
||||||
);
|
);
|
||||||
assert_eq!(len, decoded_len);
|
assert_eq!(len, decoded_len);
|
||||||
|
|
||||||
#[cfg(all(feature = "serde", feature = "alloc"))]
|
#[cfg(feature = "serde")]
|
||||||
// skip_fixed_array_length is not supposed on 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 {
|
if !C::SKIP_FIXED_ARRAY_LENGTH {
|
||||||
let encoded = bincode::serde::encode_to_vec(&element, config).unwrap();
|
let len = len.unwrap();
|
||||||
assert_eq!(&buffer[..len], &encoded);
|
let (decoded, decoded_len): (V, usize) = decoded.unwrap();
|
||||||
let (decoded, decoded_len) = bincode::serde::decode_from_slice(&encoded, config).unwrap();
|
println!(
|
||||||
|
"{:?} ({}): {:?} ({:?})",
|
||||||
|
element,
|
||||||
|
core::any::type_name::<V>(),
|
||||||
|
&buffer[..len],
|
||||||
|
core::any::type_name::<C>()
|
||||||
|
);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
cmp(&element, &decoded),
|
cmp(&element, &decoded),
|
||||||
"Comparison failed\nDecoded: {:?}\nExpected: {:?}\nBytes: {:?}",
|
"Comparison failed\nDecoded: {:?}\nExpected: {:?}\nBytes: {:?}",
|
||||||
|
|
@ -40,7 +63,12 @@ where
|
||||||
element,
|
element,
|
||||||
&buffer[..len],
|
&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),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue