Add source() method for structs

This commit is contained in:
David Tolnay 2019-10-09 06:57:15 -07:00
parent 1f02d8d9fd
commit f1dcfe0f0a
No known key found for this signature in database
GPG key ID: F9BA143B95FF6D82

View file

@ -1,6 +1,9 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{Data, DataEnum, DataStruct, DeriveInput, Error, Result, FieldsNamed, FieldsUnnamed, Fields};
use syn::{
Data, DataEnum, DataStruct, DeriveInput, Error, Fields, FieldsNamed, FieldsUnnamed, Member,
Result,
};
pub fn derive(input: &DeriveInput) -> Result<TokenStream> {
match &input.data {
@ -14,32 +17,42 @@ pub fn derive(input: &DeriveInput) -> Result<TokenStream> {
}
fn struct_error(input: &DeriveInput, data: &DataStruct) -> Result<TokenStream> {
match &data.fields {
Fields::Named(fields) => braced_struct_error(input, fields),
Fields::Unnamed(fields) => tuple_struct_error(input, fields),
Fields::Unit => unit_struct_error(input),
}
}
fn braced_struct_error(input: &DeriveInput, fields: &FieldsNamed) -> Result<TokenStream> {
let _ = input;
let _ = fields;
unimplemented!()
}
fn tuple_struct_error(input: &DeriveInput, fields: &FieldsUnnamed) -> Result<TokenStream> {
let _ = input;
let _ = fields;
unimplemented!()
}
fn unit_struct_error(input: &DeriveInput) -> Result<TokenStream> {
let ident = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let source = match &data.fields {
Fields::Named(fields) => braced_struct_source(input, fields)?,
Fields::Unnamed(fields) => tuple_struct_source(input, fields)?,
Fields::Unit => None,
};
let source_method = source.map(|source| {
quote! {
fn source(&self) -> std::option::Option<&(dyn std::error::Error + 'static)> {
std::option::Option::Some(&self.#source)
}
}
});
Ok(quote! {
impl std::error::Error for #ident {}
impl #impl_generics std::error::Error for #ident #ty_generics #where_clause {
#source_method
}
})
}
fn braced_struct_source(input: &DeriveInput, fields: &FieldsNamed) -> Result<Option<Member>> {
let _ = input;
let _ = fields;
unimplemented!()
}
fn tuple_struct_source(input: &DeriveInput, fields: &FieldsUnnamed) -> Result<Option<Member>> {
let _ = input;
let _ = fields;
unimplemented!()
}
fn enum_error(input: &DeriveInput, data: &DataEnum) -> Result<TokenStream> {
let _ = input;
let _ = data;