From 5c8a9309bbd9b2eb930727966f5b0c361a86e6fa Mon Sep 17 00:00:00 2001 From: Trangar Date: Sun, 23 Jan 2022 10:10:36 +0100 Subject: [PATCH] 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 --- derive/src/derive_enum.rs | 2 +- tests/alloc.rs | 2 +- tests/derive.rs | 178 +++++++++++++++++++++++++++++--------- tests/std.rs | 2 +- tests/utils.rs | 6 +- 5 files changed, 144 insertions(+), 46 deletions(-) diff --git a/derive/src/derive_enum.rs b/derive/src/derive_enum.rs index 3257af82..2b643a69 100644 --- a/derive/src/derive_enum.rs +++ b/derive/src/derive_enum.rs @@ -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") diff --git a/tests/alloc.rs b/tests/alloc.rs index 688db374..7fe3c9ca 100644 --- a/tests/alloc.rs +++ b/tests/alloc.rs @@ -16,7 +16,7 @@ struct Foo { pub b: u32, } -impl bincode::enc::Encode for Foo { +impl bincode::Encode for Foo { fn encode( &self, encoder: &mut E, diff --git a/tests/derive.rs b/tests/derive.rs index 84b5056e..dfb7d4e0 100644 --- a/tests/derive.rs +++ b/tests/derive.rs @@ -7,38 +7,6 @@ pub(crate) struct Test { c: u8, } -#[derive(bincode::Decode, PartialEq, Debug, Eq)] -pub struct Test2 { - 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 { + 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,6 +116,26 @@ fn test_decode_enum_struct_variant() { assert_eq!(len, 2); } +#[test] +fn test_decode_enum_unit_variant() { + let start = TestEnum::Foo; + let mut slice = [0]; + let (result, len): (TestEnum, usize) = + bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap(); + assert_eq!(result, start); + assert_eq!(len, 1); +} + +#[test] +fn test_encode_enum_unit_variant() { + let start = TestEnum::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_enum_tuple_variant() { let start = TestEnum::Baz(5, 10, 1024); @@ -136,18 +147,55 @@ fn test_encode_enum_tuple_variant() { } #[test] -fn test_decode_enum_unit_variant() { - let start = TestEnum::Foo; - let mut slice = [0]; +fn test_decode_enum_tuple_variant() { + let start = TestEnum::Baz(5, 10, 1024); + let mut slice = [2, 5, 10, 251, 0, 4]; let (result, len): (TestEnum, usize) = bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap(); assert_eq!(result, start); + 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_enum_unit_variant() { - let start = TestEnum::Foo; +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(); @@ -156,10 +204,20 @@ fn test_encode_enum_unit_variant() { } #[test] -fn test_decode_enum_tuple_variant() { - let start = TestEnum::Baz(5, 10, 1024); +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): (TestEnum, usize) = + let (result, len): (TestEnum2, usize) = bincode::decode_from_slice(&mut slice, bincode::config::standard()).unwrap(); assert_eq!(result, start); assert_eq!(len, 6); @@ -267,3 +325,43 @@ fn test_empty_enum_decode() { } ); } + +#[derive(bincode::Encode, bincode::Decode, PartialEq, Debug, Eq)] +pub enum TestWithGeneric { + 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 = + 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); +} diff --git a/tests/std.rs b/tests/std.rs index 882adebf..316d41d9 100644 --- a/tests/std.rs +++ b/tests/std.rs @@ -18,7 +18,7 @@ struct Foo { pub b: u32, } -impl bincode::enc::Encode for Foo { +impl bincode::Encode for Foo { fn encode( &self, encoder: &mut E, diff --git a/tests/utils.rs b/tests/utils.rs index 1368796c..01c3eb8e 100644 --- a/tests/utils.rs +++ b/tests/utils.rs @@ -2,7 +2,7 @@ use core::fmt::Debug; fn the_same_with_config(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(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(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); }