Bumped virtue to 0.0.13 (#626)

Co-authored-by: Victor Koenders <victor.koenders@qrtech.se>
This commit is contained in:
Trangar 2023-03-30 13:08:23 +02:00 committed by GitHub
parent 9880abe499
commit a6a5c41038
6 changed files with 149 additions and 105 deletions

View File

@ -19,4 +19,4 @@ description = "Implementation of #[derive(Encode, Decode)] for bincode"
proc-macro = true proc-macro = true
[dependencies] [dependencies]
virtue = "0.0.11" virtue = "0.0.13"

View File

@ -60,11 +60,10 @@ impl DeriveEnum {
// if we have any fields, declare them here // if we have any fields, declare them here
// Self::Variant { a, b, c } // Self::Variant { a, b, c }
if let Some(delimiter) = variant.fields.delimiter() { if let Some(fields) = variant.fields.as_ref() {
let delimiter = fields.delimiter();
match_body.group(delimiter, |field_body| { match_body.group(delimiter, |field_body| {
for (idx, field_name) in for (idx, field_name) in fields.names().into_iter().enumerate() {
variant.fields.names().into_iter().enumerate()
{
if idx != 0 { if idx != 0 {
field_body.punct(','); field_body.punct(',');
} }
@ -104,23 +103,25 @@ impl DeriveEnum {
body.punct('?'); body.punct('?');
body.punct(';'); body.punct(';');
// If we have any fields, encode them all one by one // If we have any fields, encode them all one by one
for field_name in variant.fields.names() { if let Some(fields) = variant.fields.as_ref() {
let attributes = field_name for field_name in fields.names() {
.attributes() let attributes = field_name
.get_attribute::<FieldAttributes>()? .attributes()
.unwrap_or_default(); .get_attribute::<FieldAttributes>()?
if attributes.with_serde { .unwrap_or_default();
body.push_parsed(format!( if attributes.with_serde {
body.push_parsed(format!(
"{0}::Encode::encode(&{0}::serde::Compat({1}), encoder)?;", "{0}::Encode::encode(&{0}::serde::Compat({1}), encoder)?;",
crate_name, crate_name,
field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX), field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX),
))?; ))?;
} else { } else {
body.push_parsed(format!( body.push_parsed(format!(
"{0}::Encode::encode({1}, encoder)?;", "{0}::Encode::encode({1}, encoder)?;",
crate_name, crate_name,
field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX), field_name.to_string_with_prefix(TUPLE_FIELD_PREFIX),
))?; ))?;
}
} }
} }
body.push_parsed("Ok(())")?; body.push_parsed("Ok(())")?;
@ -181,7 +182,7 @@ impl DeriveEnum {
variant_inner.ident_str("allowed"); variant_inner.ident_str("allowed");
variant_inner.punct(':'); variant_inner.punct(':');
if self.variants.iter().any(|i| i.has_fixed_value()) { if self.variants.iter().any(|i| i.value.is_some()) {
// we have fixed values, implement AllowedEnumVariants::Allowed // we have fixed values, implement AllowedEnumVariants::Allowed
variant_inner.push_parsed(format!( variant_inner.push_parsed(format!(
"&{}::error::AllowedEnumVariants::Allowed", "&{}::error::AllowedEnumVariants::Allowed",
@ -230,7 +231,7 @@ impl DeriveEnum {
where_constraints.push_parsed_constraint(bounds).map_err(|e| e.with_span(lit.span()))?; where_constraints.push_parsed_constraint(bounds).map_err(|e| e.with_span(lit.span()))?;
} else { } else {
for g in generics.iter_generics() { for g in generics.iter_generics() {
where_constraints.push_constraint(g, format!("{}::Decode", crate_name)).unwrap(); where_constraints.push_constraint(g, format!("{}::Decode", crate_name))?;
} }
} }
Ok(()) Ok(())
@ -272,27 +273,29 @@ impl DeriveEnum {
variant_case_body.ident(variant.name.clone()); variant_case_body.ident(variant.name.clone());
variant_case_body.group(Delimiter::Brace, |variant_body| { variant_case_body.group(Delimiter::Brace, |variant_body| {
let is_tuple = matches!(variant.fields, Fields::Tuple(_)); if let Some(fields) = variant.fields.as_ref() {
for (idx, field) in variant.fields.names().into_iter().enumerate() { let is_tuple = matches!(fields, Fields::Tuple(_));
if is_tuple { for (idx, field) in fields.names().into_iter().enumerate() {
variant_body.lit_usize(idx); if is_tuple {
} else { variant_body.lit_usize(idx);
variant_body.ident(field.unwrap_ident().clone()); } else {
} variant_body.ident(field.unwrap_ident().clone());
variant_body.punct(':'); }
let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default(); variant_body.punct(':');
if attributes.with_serde { let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default();
variant_body if attributes.with_serde {
.push_parsed(format!( variant_body
"<{0}::serde::Compat<_> as {0}::Decode>::decode(decoder)?.0,", .push_parsed(format!(
crate_name "<{0}::serde::Compat<_> as {0}::Decode>::decode(decoder)?.0,",
))?; crate_name
} else { ))?;
variant_body } else {
.push_parsed(format!( variant_body
"{}::Decode::decode(decoder)?,", .push_parsed(format!(
crate_name "{}::Decode::decode(decoder)?,",
))?; crate_name
))?;
}
} }
} }
Ok(()) Ok(())
@ -327,6 +330,9 @@ impl DeriveEnum {
for g in generics.iter_generics() { for g in generics.iter_generics() {
where_constraints.push_constraint(g, format!("{}::de::BorrowDecode<'__de>", crate_name)).unwrap(); where_constraints.push_constraint(g, format!("{}::de::BorrowDecode<'__de>", crate_name)).unwrap();
} }
for lt in generics.iter_lifetimes() {
where_constraints.push_parsed_constraint(format!("'__de: '{}", lt.ident))?;
}
} }
Ok(()) Ok(())
})? })?
@ -364,20 +370,22 @@ impl DeriveEnum {
variant_case_body.ident(variant.name.clone()); variant_case_body.ident(variant.name.clone());
variant_case_body.group(Delimiter::Brace, |variant_body| { variant_case_body.group(Delimiter::Brace, |variant_body| {
let is_tuple = matches!(variant.fields, Fields::Tuple(_)); if let Some(fields) = variant.fields.as_ref() {
for (idx, field) in variant.fields.names().into_iter().enumerate() { let is_tuple = matches!(fields, Fields::Tuple(_));
if is_tuple { for (idx, field) in fields.names().into_iter().enumerate() {
variant_body.lit_usize(idx); if is_tuple {
} else { variant_body.lit_usize(idx);
variant_body.ident(field.unwrap_ident().clone()); } else {
} variant_body.ident(field.unwrap_ident().clone());
variant_body.punct(':'); }
let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default(); variant_body.punct(':');
if attributes.with_serde { let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default();
variant_body if attributes.with_serde {
.push_parsed(format!("<{0}::serde::BorrowCompat<_> as {0}::BorrowDecode>::borrow_decode(decoder)?.0,", crate_name))?; variant_body
} else { .push_parsed(format!("<{0}::serde::BorrowCompat<_> as {0}::BorrowDecode>::borrow_decode(decoder)?.0,", crate_name))?;
variant_body.push_parsed(format!("{}::BorrowDecode::borrow_decode(decoder)?,", crate_name))?; } else {
variant_body.push_parsed(format!("{}::BorrowDecode::borrow_decode(decoder)?,", crate_name))?;
}
} }
} }
Ok(()) Ok(())

View File

@ -4,7 +4,7 @@ use virtue::parse::Fields;
use virtue::prelude::*; use virtue::prelude::*;
pub(crate) struct DeriveStruct { pub(crate) struct DeriveStruct {
pub fields: Fields, pub fields: Option<Fields>,
pub attributes: ContainerAttributes, pub attributes: ContainerAttributes,
} }
@ -39,21 +39,23 @@ impl DeriveStruct {
crate_name crate_name
)) ))
.body(|fn_body| { .body(|fn_body| {
for field in self.fields.names() { if let Some(fields) = self.fields.as_ref() {
let attributes = field for field in fields.names() {
.attributes() let attributes = field
.get_attribute::<FieldAttributes>()? .attributes()
.unwrap_or_default(); .get_attribute::<FieldAttributes>()?
if attributes.with_serde { .unwrap_or_default();
fn_body.push_parsed(format!( if attributes.with_serde {
"{0}::Encode::encode(&{0}::serde::Compat(&self.{1}), encoder)?;", fn_body.push_parsed(format!(
crate_name, field "{0}::Encode::encode(&{0}::serde::Compat(&self.{1}), encoder)?;",
))?; crate_name, field
} else { ))?;
fn_body.push_parsed(format!( } else {
"{}::Encode::encode(&self.{}, encoder)?;", fn_body.push_parsed(format!(
crate_name, field "{}::Encode::encode(&self.{}, encoder)?;",
))?; crate_name, field
))?;
}
} }
} }
fn_body.push_parsed("Ok(())")?; fn_body.push_parsed("Ok(())")?;
@ -95,22 +97,24 @@ impl DeriveStruct {
// b: bincode::Decode::decode(decoder)?, // b: bincode::Decode::decode(decoder)?,
// ... // ...
// } // }
for field in &self.fields.names() { if let Some(fields) = self.fields.as_ref() {
let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default(); for field in fields.names() {
if attributes.with_serde { let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default();
struct_body if attributes.with_serde {
.push_parsed(format!( struct_body
"{1}: (<{0}::serde::Compat<_> as {0}::Decode>::decode(decoder)?).0,", .push_parsed(format!(
crate_name, "{1}: (<{0}::serde::Compat<_> as {0}::Decode>::decode(decoder)?).0,",
field crate_name,
))?; field
} else { ))?;
struct_body } else {
.push_parsed(format!( struct_body
"{1}: {0}::Decode::decode(decoder)?,", .push_parsed(format!(
crate_name, "{1}: {0}::Decode::decode(decoder)?,",
field crate_name,
))?; field
))?;
}
} }
} }
Ok(()) Ok(())
@ -137,6 +141,9 @@ impl DeriveStruct {
for g in generics.iter_generics() { for g in generics.iter_generics() {
where_constraints.push_constraint(g, format!("{}::de::BorrowDecode<'__de>", crate_name)).unwrap(); where_constraints.push_constraint(g, format!("{}::de::BorrowDecode<'__de>", crate_name)).unwrap();
} }
for lt in generics.iter_lifetimes() {
where_constraints.push_parsed_constraint(format!("'__de: '{}", lt.ident))?;
}
} }
Ok(()) Ok(())
})? })?
@ -150,22 +157,24 @@ impl DeriveStruct {
fn_body.group(Delimiter::Parenthesis, |ok_group| { fn_body.group(Delimiter::Parenthesis, |ok_group| {
ok_group.ident_str("Self"); ok_group.ident_str("Self");
ok_group.group(Delimiter::Brace, |struct_body| { ok_group.group(Delimiter::Brace, |struct_body| {
for field in self.fields.names() { if let Some(fields) = self.fields.as_ref() {
let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default(); for field in fields.names() {
if attributes.with_serde { let attributes = field.attributes().get_attribute::<FieldAttributes>()?.unwrap_or_default();
struct_body if attributes.with_serde {
.push_parsed(format!( struct_body
"{1}: (<{0}::serde::BorrowCompat<_> as {0}::BorrowDecode>::borrow_decode(decoder)?).0,", .push_parsed(format!(
crate_name, "{1}: (<{0}::serde::BorrowCompat<_> as {0}::BorrowDecode>::borrow_decode(decoder)?).0,",
field crate_name,
))?; field
} else { ))?;
struct_body } else {
.push_parsed(format!( struct_body
"{1}: {0}::BorrowDecode::borrow_decode(decoder)?,", .push_parsed(format!(
crate_name, "{1}: {0}::BorrowDecode::borrow_decode(decoder)?,",
field crate_name,
))?; field
))?;
}
} }
} }
Ok(()) Ok(())

View File

@ -35,3 +35,6 @@ mod issue_570;
#[path = "issues/issue_592.rs"] #[path = "issues/issue_592.rs"]
mod issue_592; mod issue_592;
#[path = "issues/issue_614.rs"]
mod issue_614;

View File

@ -7,13 +7,15 @@ use std::borrow::Cow;
use std::string::String; use std::string::String;
#[derive(Decode, Encode, PartialEq, Debug)] #[derive(Decode, Encode, PartialEq, Debug)]
#[bincode(borrow_decode_bounds = "&'__de U<'a, A>: ::bincode::de::BorrowDecode<'__de> + '__de")] #[bincode(
borrow_decode_bounds = "&'__de U<'a, A>: ::bincode::de::BorrowDecode<'__de> + '__de, '__de: 'a"
)]
struct T<'a, A: Clone + Encode + Decode> { struct T<'a, A: Clone + Encode + Decode> {
t: Cow<'a, U<'a, A>>, t: Cow<'a, U<'a, A>>,
} }
#[derive(Clone, Decode, Encode, PartialEq, Debug)] #[derive(Clone, Decode, Encode, PartialEq, Debug)]
#[bincode(borrow_decode_bounds = "&'__de A: ::bincode::de::BorrowDecode<'__de> + '__de")] #[bincode(borrow_decode_bounds = "&'__de A: ::bincode::de::BorrowDecode<'__de> + '__de, '__de: 'a")]
struct U<'a, A: Clone + Encode + Decode> { struct U<'a, A: Clone + Encode + Decode> {
u: Cow<'a, A>, u: Cow<'a, A>,
} }

22
tests/issues/issue_614.rs Normal file
View File

@ -0,0 +1,22 @@
#![cfg(feature = "derive")]
use bincode::{Decode, Encode};
#[derive(Encode, Decode, Clone)]
pub struct A;
#[derive(Encode, Decode, Clone)]
pub struct B<T>
where
T: Clone + Encode + Decode,
{
pub t: T,
}
#[derive(Encode, Decode)]
pub struct MyStruct<T>
where
T: Clone + Encode + Decode,
{
pub a: A,
pub b: B<T>,
}