Skip to content

Commit

Permalink
Fix tuple struct encoding in serde (#549)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZoeyR authored Jun 4, 2022
1 parent 6ec69a3 commit 5b19220
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
7 changes: 7 additions & 0 deletions compatibility/src/misc.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
#[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));
super::test_same(Result::<u32, u8>::Err(5));
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);
5 changes: 2 additions & 3 deletions src/features/serde/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 })
}

Expand Down
3 changes: 3 additions & 0 deletions tests/issues.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ mod issue_500;

#[path = "issues/issue_523.rs"]
mod issue_523;

#[path = "issues/issue_547.rs"]
mod issue_547;
24 changes: 24 additions & 0 deletions tests/issues/issue_547.rs
Original file line number Diff line number Diff line change
@@ -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);
}
34 changes: 25 additions & 9 deletions tests/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
40 changes: 34 additions & 6 deletions tests/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,48 @@ 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: {:?}",
decoded,
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),
}
}
}

Expand Down

0 comments on commit 5b19220

Please sign in to comment.