Add generic bound support to derive
This commit is contained in:
parent
f914b3e580
commit
8241e6c656
|
|
@ -1,15 +1,16 @@
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
use quote::{quote, quote_spanned};
|
||||||
use syn::{spanned::Spanned, Ident};
|
use syn::{spanned::Spanned, Generics, Ident};
|
||||||
|
|
||||||
pub struct DeriveStruct {
|
pub struct DeriveStruct {
|
||||||
name: Ident,
|
name: Ident,
|
||||||
|
generics: Generics,
|
||||||
fields: Vec<Ident>,
|
fields: Vec<Ident>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeriveStruct {
|
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 {
|
let fields = match str.fields {
|
||||||
syn::Fields::Named(fields) => fields
|
syn::Fields::Named(fields) => fields
|
||||||
.named
|
.named
|
||||||
|
|
@ -24,11 +25,21 @@ impl DeriveStruct {
|
||||||
.collect(),
|
.collect(),
|
||||||
syn::Fields::Unit => Vec::new(),
|
syn::Fields::Unit => Vec::new(),
|
||||||
};
|
};
|
||||||
Ok(Self { name, fields })
|
Ok(Self {
|
||||||
|
name,
|
||||||
|
generics,
|
||||||
|
fields,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_encodable(self) -> Result<TokenStream> {
|
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
|
let fields = fields
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -40,7 +51,7 @@ impl DeriveStruct {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let result = quote! {
|
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> {
|
fn encode<E: bincode::enc::Encode>(&self, mut encoder: E) -> Result<(), bincode::error::EncodeError> {
|
||||||
#(#fields)*
|
#(#fields)*
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ pub fn derive_encodable(input: TokenStream) -> TokenStream {
|
||||||
fn derive_encodable_inner(input: DeriveInput) -> Result<TokenStream> {
|
fn derive_encodable_inner(input: DeriveInput) -> Result<TokenStream> {
|
||||||
match input.data {
|
match input.data {
|
||||||
syn::Data::Struct(struct_definition) => {
|
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) => {
|
syn::Data::Enum(enum_definition) => {
|
||||||
DeriveEnum::parse(input.ident, enum_definition).and_then(|str| str.to_encodable())
|
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> {
|
fn derive_decodable_inner(input: DeriveInput) -> Result<TokenStream> {
|
||||||
match input.data {
|
match input.data {
|
||||||
syn::Data::Struct(struct_definition) => {
|
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) => {
|
syn::Data::Enum(enum_definition) => {
|
||||||
DeriveEnum::parse(input.ident, enum_definition).and_then(|str| str.to_decodable())
|
DeriveEnum::parse(input.ident, enum_definition).and_then(|str| str.to_decodable())
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
use bincode::enc::Encodeable;
|
||||||
|
|
||||||
#[derive(bincode::Encodable, PartialEq, Debug)]
|
#[derive(bincode::Encodable, PartialEq, Debug)]
|
||||||
pub struct Test {
|
pub struct Test<T: Encodeable> {
|
||||||
a: i32,
|
a: T,
|
||||||
b: u32,
|
b: u32,
|
||||||
c: u8,
|
c: u8,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue