Skip to content

Commit

Permalink
Fixed an error in bincode derive where it would implement the wrong t…
Browse files Browse the repository at this point in the history
…rait 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
  • Loading branch information
VictorKoenders committed Jan 23, 2022
1 parent 919ac4f commit 5c8a930
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 46 deletions.
2 changes: 1 addition & 1 deletion derive/src/derive_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion tests/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
178 changes: 138 additions & 40 deletions tests/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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() {
Expand All @@ -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 {
Expand All @@ -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);
Expand All @@ -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 };
Expand All @@ -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);
Expand All @@ -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();
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}
2 changes: 1 addition & 1 deletion tests/std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions tests/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
{
Expand All @@ -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
Expand Down Expand Up @@ -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);
}

0 comments on commit 5c8a930

Please sign in to comment.