Fixed an error in bincode derive where it would implement the wrong trait if a generic parameter is present (#487)

* Fixed an error in bincode derive where it would implement the wrong trait if a generic parameter is present

* Reorganized the derive tests, added a roundtrip test for an enum with generics

* I didn't forget cargo fmt I swear

* Simplified some paths
This commit is contained in:
Trangar 2022-01-23 10:10:36 +01:00 committed by GitHub
parent 20e4a02ea3
commit d0fd1a98cd
5 changed files with 146 additions and 48 deletions

View File

@ -196,7 +196,7 @@ impl DeriveEnum {
.impl_for("bincode::Decode")?
.modify_generic_constraints(|generics, where_constraints| {
for g in generics.iter_generics() {
where_constraints.push_constraint(g, "bincode::enc::Decode").unwrap();
where_constraints.push_constraint(g, "bincode::Decode").unwrap();
}
})
.generate_fn("decode")

View File

@ -16,7 +16,7 @@ struct Foo {
pub b: u32,
}
impl bincode::enc::Encode for Foo {
impl bincode::Encode for Foo {
fn encode<E: bincode::enc::Encoder>(
&self,
encoder: &mut E,

View File

@ -7,38 +7,6 @@ pub(crate) struct Test<T> {
c: u8,
}
#[derive(bincode::Decode, PartialEq, Debug, Eq)]
pub struct Test2<T> {
a: T,
b: u32,
c: u32,
}
#[derive(bincode::BorrowDecode, bincode::Encode, PartialEq, Debug, Eq)]
pub struct Test3<'a> {
a: &'a str,
b: u32,
c: u32,
d: Option<&'a [u8]>,
}
#[derive(bincode::Encode, bincode::Decode, PartialEq, Debug, Eq)]
pub struct TestTupleStruct(u32, u32, u32);
#[derive(bincode::Encode, bincode::Decode, PartialEq, Debug, Eq)]
pub enum TestEnum {
Foo,
Bar { name: u32 },
Baz(u32, u32, u32),
}
#[derive(bincode::Encode, bincode::BorrowDecode, PartialEq, Debug, Eq)]
pub enum TestEnum2<'a> {
Foo,
Bar { name: &'a str },
Baz(u32, u32, u32),
}
#[test]
fn test_encode() {
let start = Test {
@ -52,6 +20,12 @@ fn test_encode() {
assert_eq!(bytes_written, 3);
assert_eq!(&slice[..bytes_written], &[10, 10, 20]);
}
#[derive(bincode::Decode, PartialEq, Debug, Eq)]
pub struct Test2<T> {
a: T,
b: u32,
c: u32,
}
#[test]
fn test_decode() {
@ -67,6 +41,14 @@ fn test_decode() {
assert_eq!(len, 5);
}
#[derive(bincode::BorrowDecode, bincode::Encode, PartialEq, Debug, Eq)]
pub struct Test3<'a> {
a: &'a str,
b: u32,
c: u32,
d: Option<&'a [u8]>,
}
#[test]
fn test_encode_decode_str() {
let start = Test3 {
@ -85,6 +67,9 @@ fn test_encode_decode_str() {
assert_eq!(len, 21);
}
#[derive(bincode::Encode, bincode::Decode, PartialEq, Debug, Eq)]
pub struct TestTupleStruct(u32, u32, u32);
#[test]
fn test_encode_tuple() {
let start = TestTupleStruct(5, 10, 1024);
@ -105,6 +90,12 @@ fn test_decode_tuple() {
assert_eq!(len, 5);
}
#[derive(bincode::Encode, bincode::Decode, PartialEq, Debug, Eq)]
pub enum TestEnum {
Foo,
Bar { name: u32 },
Baz(u32, u32, u32),
}
#[test]
fn test_encode_enum_struct_variant() {
let start = TestEnum::Bar { name: 5u32 };
@ -125,16 +116,6 @@ fn test_decode_enum_struct_variant() {
assert_eq!(len, 2);
}
#[test]
fn test_encode_enum_tuple_variant() {
let start = TestEnum::Baz(5, 10, 1024);
let mut slice = [0u8; 1024];
let bytes_written =
bincode::encode_into_slice(start, &mut slice, bincode::config::standard()).unwrap();
assert_eq!(bytes_written, 6);
assert_eq!(&slice[..bytes_written], &[2, 5, 10, 251, 0, 4]);
}
#[test]
fn test_decode_enum_unit_variant() {
let start = TestEnum::Foo;
@ -155,6 +136,16 @@ fn test_encode_enum_unit_variant() {
assert_eq!(&slice[..bytes_written], &[0]);
}
#[test]
fn test_encode_enum_tuple_variant() {
let start = TestEnum::Baz(5, 10, 1024);
let mut slice = [0u8; 1024];
let bytes_written =
bincode::encode_into_slice(start, &mut slice, bincode::config::standard()).unwrap();
assert_eq!(bytes_written, 6);
assert_eq!(&slice[..bytes_written], &[2, 5, 10, 251, 0, 4]);
}
#[test]
fn test_decode_enum_tuple_variant() {
let start = TestEnum::Baz(5, 10, 1024);
@ -165,6 +156,73 @@ fn test_decode_enum_tuple_variant() {
assert_eq!(len, 6);
}
#[derive(bincode::Encode, bincode::BorrowDecode, PartialEq, Debug, Eq)]
pub enum TestEnum2<'a> {
Foo,
Bar { name: &'a str },
Baz(u32, u32, u32),
}
#[test]
fn test_encode_borrowed_enum_struct_variant() {
let start = TestEnum2::Bar { name: "foo" };
let mut slice = [0u8; 1024];
let bytes_written =
bincode::encode_into_slice(start, &mut slice, bincode::config::standard()).unwrap();
assert_eq!(bytes_written, 5);
assert_eq!(&slice[..bytes_written], &[1, 3, 102, 111, 111]);
}
#[test]
fn test_decode_borrowed_enum_struct_variant() {
let start = TestEnum2::Bar { name: "foo" };
let mut slice = [1, 3, 102, 111, 111];
let (result, len): (TestEnum2, usize) =
bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap();
assert_eq!(result, start);
assert_eq!(len, 5);
}
#[test]
fn test_decode_borrowed_enum_unit_variant() {
let start = TestEnum2::Foo;
let mut slice = [0];
let (result, len): (TestEnum2, usize) =
bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap();
assert_eq!(result, start);
assert_eq!(len, 1);
}
#[test]
fn test_encode_borrowed_enum_unit_variant() {
let start = TestEnum2::Foo;
let mut slice = [0u8; 1024];
let bytes_written =
bincode::encode_into_slice(start, &mut slice, bincode::config::standard()).unwrap();
assert_eq!(bytes_written, 1);
assert_eq!(&slice[..bytes_written], &[0]);
}
#[test]
fn test_encode_borrowed_enum_tuple_variant() {
let start = TestEnum2::Baz(5, 10, 1024);
let mut slice = [0u8; 1024];
let bytes_written =
bincode::encode_into_slice(start, &mut slice, bincode::config::standard()).unwrap();
assert_eq!(bytes_written, 6);
assert_eq!(&slice[..bytes_written], &[2, 5, 10, 251, 0, 4]);
}
#[test]
fn test_decode_borrowed_enum_tuple_variant() {
let start = TestEnum2::Baz(5, 10, 1024);
let mut slice = [2, 5, 10, 251, 0, 4];
let (result, len): (TestEnum2, usize) =
bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap();
assert_eq!(result, start);
assert_eq!(len, 6);
}
#[derive(bincode::Decode, bincode::Encode, PartialEq, Eq, Debug)]
enum CStyleEnum {
A = 1,
@ -267,3 +325,43 @@ fn test_empty_enum_decode() {
}
);
}
#[derive(bincode::Encode, bincode::Decode, PartialEq, Debug, Eq)]
pub enum TestWithGeneric<T> {
Foo,
Bar(T),
}
#[test]
fn test_enum_with_generics_roundtrip() {
let start = TestWithGeneric::Bar(1234);
let mut slice = [0u8; 10];
let bytes_written =
bincode::encode_into_slice(&start, &mut slice, bincode::config::standard()).unwrap();
assert_eq!(
&slice[..bytes_written],
&[
1, // variant 1
251, // u16
210, 4 // 1234
]
);
let decoded: TestWithGeneric<u32> =
bincode::decode_from_slice(&slice[..bytes_written], bincode::config::standard())
.unwrap()
.0;
assert_eq!(start, decoded);
let start = TestWithGeneric::<()>::Foo;
let mut slice = [0u8; 10];
let bytes_written =
bincode::encode_into_slice(&start, &mut slice, bincode::config::standard()).unwrap();
assert_eq!(&slice[..bytes_written], &[0]);
let decoded: TestWithGeneric<()> =
bincode::decode_from_slice(&slice[..bytes_written], bincode::config::standard())
.unwrap()
.0;
assert_eq!(start, decoded);
}

View File

@ -18,7 +18,7 @@ struct Foo {
pub b: u32,
}
impl bincode::enc::Encode for Foo {
impl bincode::Encode for Foo {
fn encode<E: bincode::enc::Encoder>(
&self,
encoder: &mut E,

View File

@ -2,7 +2,7 @@ use core::fmt::Debug;
fn the_same_with_config<V, C, CMP>(element: &V, config: C, cmp: CMP)
where
V: bincode::enc::Encode + bincode::Decode + Debug + 'static,
V: bincode::Encode + bincode::Decode + Debug + 'static,
C: bincode::config::Config,
CMP: Fn(&V, &V) -> bool,
{
@ -29,7 +29,7 @@ where
pub fn the_same_with_comparer<V, CMP>(element: V, cmp: CMP)
where
V: bincode::enc::Encode + bincode::Decode + Debug + 'static,
V: bincode::Encode + bincode::Decode + Debug + 'static,
CMP: Fn(&V, &V) -> bool,
{
// A matrix of each different config option possible
@ -102,7 +102,7 @@ where
#[allow(dead_code)] // This is not used in every test
pub fn the_same<V>(element: V)
where
V: bincode::enc::Encode + bincode::Decode + PartialEq + Debug + 'static,
V: bincode::Encode + bincode::Decode + PartialEq + Debug + 'static,
{
the_same_with_comparer(element, |a, b| a == b);
}