Add generic bound support to derive

This commit is contained in:
Lena Hellström 2021-09-20 15:58:16 +02:00
parent f914b3e580
commit 8241e6c656
3 changed files with 25 additions and 10 deletions

View File

@ -1,15 +1,16 @@
use crate::Result;
use proc_macro::TokenStream;
use quote::quote;
use syn::{spanned::Spanned, Ident};
use quote::{quote, quote_spanned};
use syn::{spanned::Spanned, Generics, Ident};
pub struct DeriveStruct {
name: Ident,
generics: Generics,
fields: Vec<Ident>,
}
impl DeriveStruct {
pub fn parse(name: Ident, str: syn::DataStruct) -> Result<Self> {
pub fn parse(name: Ident, generics: Generics, str: syn::DataStruct) -> Result<Self> {
let fields = match str.fields {
syn::Fields::Named(fields) => fields
.named
@ -24,11 +25,21 @@ impl DeriveStruct {
.collect(),
syn::Fields::Unit => Vec::new(),
};
Ok(Self { name, fields })
Ok(Self {
name,
generics,
fields,
})
}
pub fn to_encodable(self) -> Result<TokenStream> {
let DeriveStruct { name, fields } = self;
let DeriveStruct {
name,
generics,
fields,
} = self;
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let fields = fields
.into_iter()
@ -40,7 +51,7 @@ impl DeriveStruct {
.collect::<Vec<_>>();
let result = quote! {
impl bincode::enc::Encodeable for #name {
impl #impl_generics bincode::enc::Encodeable for #name #ty_generics #where_clause {
fn encode<E: bincode::enc::Encode>(&self, mut encoder: E) -> Result<(), bincode::error::EncodeError> {
#(#fields)*
Ok(())

View File

@ -21,7 +21,8 @@ pub fn derive_encodable(input: TokenStream) -> TokenStream {
fn derive_encodable_inner(input: DeriveInput) -> Result<TokenStream> {
match input.data {
syn::Data::Struct(struct_definition) => {
DeriveStruct::parse(input.ident, struct_definition).and_then(|str| str.to_encodable())
DeriveStruct::parse(input.ident, input.generics, struct_definition)
.and_then(|str| str.to_encodable())
}
syn::Data::Enum(enum_definition) => {
DeriveEnum::parse(input.ident, enum_definition).and_then(|str| str.to_encodable())
@ -39,7 +40,8 @@ pub fn derive_decodable(input: TokenStream) -> TokenStream {
fn derive_decodable_inner(input: DeriveInput) -> Result<TokenStream> {
match input.data {
syn::Data::Struct(struct_definition) => {
DeriveStruct::parse(input.ident, struct_definition).and_then(|str| str.to_decodable())
DeriveStruct::parse(input.ident, input.generics, struct_definition)
.and_then(|str| str.to_decodable())
}
syn::Data::Enum(enum_definition) => {
DeriveEnum::parse(input.ident, enum_definition).and_then(|str| str.to_decodable())

View File

@ -1,6 +1,8 @@
use bincode::enc::Encodeable;
#[derive(bincode::Encodable, PartialEq, Debug)]
pub struct Test {
a: i32,
pub struct Test<T: Encodeable> {
a: T,
b: u32,
c: u8,
}