mirror of https://git.sr.ht/~stygianentity/bincode
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:
parent
20e4a02ea3
commit
d0fd1a98cd
|
|
@ -196,7 +196,7 @@ impl DeriveEnum {
|
||||||
.impl_for("bincode::Decode")?
|
.impl_for("bincode::Decode")?
|
||||||
.modify_generic_constraints(|generics, where_constraints| {
|
.modify_generic_constraints(|generics, where_constraints| {
|
||||||
for g in generics.iter_generics() {
|
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")
|
.generate_fn("decode")
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ struct Foo {
|
||||||
pub b: u32,
|
pub b: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl bincode::enc::Encode for Foo {
|
impl bincode::Encode for Foo {
|
||||||
fn encode<E: bincode::enc::Encoder>(
|
fn encode<E: bincode::enc::Encoder>(
|
||||||
&self,
|
&self,
|
||||||
encoder: &mut E,
|
encoder: &mut E,
|
||||||
|
|
|
||||||
182
tests/derive.rs
182
tests/derive.rs
|
|
@ -7,38 +7,6 @@ pub(crate) struct Test<T> {
|
||||||
c: u8,
|
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]
|
#[test]
|
||||||
fn test_encode() {
|
fn test_encode() {
|
||||||
let start = Test {
|
let start = Test {
|
||||||
|
|
@ -52,6 +20,12 @@ fn test_encode() {
|
||||||
assert_eq!(bytes_written, 3);
|
assert_eq!(bytes_written, 3);
|
||||||
assert_eq!(&slice[..bytes_written], &[10, 10, 20]);
|
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]
|
#[test]
|
||||||
fn test_decode() {
|
fn test_decode() {
|
||||||
|
|
@ -67,6 +41,14 @@ fn test_decode() {
|
||||||
assert_eq!(len, 5);
|
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]
|
#[test]
|
||||||
fn test_encode_decode_str() {
|
fn test_encode_decode_str() {
|
||||||
let start = Test3 {
|
let start = Test3 {
|
||||||
|
|
@ -85,6 +67,9 @@ fn test_encode_decode_str() {
|
||||||
assert_eq!(len, 21);
|
assert_eq!(len, 21);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(bincode::Encode, bincode::Decode, PartialEq, Debug, Eq)]
|
||||||
|
pub struct TestTupleStruct(u32, u32, u32);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_encode_tuple() {
|
fn test_encode_tuple() {
|
||||||
let start = TestTupleStruct(5, 10, 1024);
|
let start = TestTupleStruct(5, 10, 1024);
|
||||||
|
|
@ -105,6 +90,12 @@ fn test_decode_tuple() {
|
||||||
assert_eq!(len, 5);
|
assert_eq!(len, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(bincode::Encode, bincode::Decode, PartialEq, Debug, Eq)]
|
||||||
|
pub enum TestEnum {
|
||||||
|
Foo,
|
||||||
|
Bar { name: u32 },
|
||||||
|
Baz(u32, u32, u32),
|
||||||
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_encode_enum_struct_variant() {
|
fn test_encode_enum_struct_variant() {
|
||||||
let start = TestEnum::Bar { name: 5u32 };
|
let start = TestEnum::Bar { name: 5u32 };
|
||||||
|
|
@ -125,16 +116,6 @@ fn test_decode_enum_struct_variant() {
|
||||||
assert_eq!(len, 2);
|
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]
|
#[test]
|
||||||
fn test_decode_enum_unit_variant() {
|
fn test_decode_enum_unit_variant() {
|
||||||
let start = TestEnum::Foo;
|
let start = TestEnum::Foo;
|
||||||
|
|
@ -155,6 +136,16 @@ fn test_encode_enum_unit_variant() {
|
||||||
assert_eq!(&slice[..bytes_written], &[0]);
|
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]
|
#[test]
|
||||||
fn test_decode_enum_tuple_variant() {
|
fn test_decode_enum_tuple_variant() {
|
||||||
let start = TestEnum::Baz(5, 10, 1024);
|
let start = TestEnum::Baz(5, 10, 1024);
|
||||||
|
|
@ -165,6 +156,73 @@ fn test_decode_enum_tuple_variant() {
|
||||||
assert_eq!(len, 6);
|
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)]
|
#[derive(bincode::Decode, bincode::Encode, PartialEq, Eq, Debug)]
|
||||||
enum CStyleEnum {
|
enum CStyleEnum {
|
||||||
A = 1,
|
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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ struct Foo {
|
||||||
pub b: u32,
|
pub b: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl bincode::enc::Encode for Foo {
|
impl bincode::Encode for Foo {
|
||||||
fn encode<E: bincode::enc::Encoder>(
|
fn encode<E: bincode::enc::Encoder>(
|
||||||
&self,
|
&self,
|
||||||
encoder: &mut E,
|
encoder: &mut E,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use core::fmt::Debug;
|
||||||
|
|
||||||
fn the_same_with_config<V, C, CMP>(element: &V, config: C, cmp: CMP)
|
fn the_same_with_config<V, C, CMP>(element: &V, config: C, cmp: CMP)
|
||||||
where
|
where
|
||||||
V: bincode::enc::Encode + bincode::Decode + Debug + 'static,
|
V: bincode::Encode + bincode::Decode + Debug + 'static,
|
||||||
C: bincode::config::Config,
|
C: bincode::config::Config,
|
||||||
CMP: Fn(&V, &V) -> bool,
|
CMP: Fn(&V, &V) -> bool,
|
||||||
{
|
{
|
||||||
|
|
@ -29,7 +29,7 @@ where
|
||||||
|
|
||||||
pub fn the_same_with_comparer<V, CMP>(element: V, cmp: CMP)
|
pub fn the_same_with_comparer<V, CMP>(element: V, cmp: CMP)
|
||||||
where
|
where
|
||||||
V: bincode::enc::Encode + bincode::Decode + Debug + 'static,
|
V: bincode::Encode + bincode::Decode + Debug + 'static,
|
||||||
CMP: Fn(&V, &V) -> bool,
|
CMP: Fn(&V, &V) -> bool,
|
||||||
{
|
{
|
||||||
// A matrix of each different config option possible
|
// A matrix of each different config option possible
|
||||||
|
|
@ -102,7 +102,7 @@ where
|
||||||
#[allow(dead_code)] // This is not used in every test
|
#[allow(dead_code)] // This is not used in every test
|
||||||
pub fn the_same<V>(element: V)
|
pub fn the_same<V>(element: V)
|
||||||
where
|
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);
|
the_same_with_comparer(element, |a, b| a == b);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue