1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
use proc_macro2; use syn; use model::*; use util::*; pub fn derive(item: syn::DeriveInput) -> Result<proc_macro2::TokenStream, Diagnostic> { let model = Model::from_item(&item)?; let struct_name = &item.ident; let field_ty = model .fields() .iter() .map(|f| f.ty_for_deserialize()) .collect::<Result<Vec<_>, _>>()?; let field_ty = &field_ty; let build_expr = model.fields().iter().enumerate().map(|(i, f)| { let i = syn::Index::from(i); f.name.assign(parse_quote!(row.#i.into())) }); let (_, ty_generics, _) = item.generics.split_for_impl(); let mut generics = item.generics.clone(); generics .params .push(parse_quote!(__DB: diesel::backend::Backend)); generics.params.push(parse_quote!(__ST)); { let where_clause = generics.where_clause.get_or_insert(parse_quote!(where)); where_clause .predicates .push(parse_quote!((#(#field_ty,)*): Queryable<__ST, __DB>)); } let (impl_generics, _, where_clause) = generics.split_for_impl(); Ok(wrap_in_dummy_mod( model.dummy_mod_name("queryable"), quote! { use diesel::Queryable; impl #impl_generics Queryable<__ST, __DB> for #struct_name #ty_generics #where_clause { type Row = <(#(#field_ty,)*) as Queryable<__ST, __DB>>::Row; fn build(row: Self::Row) -> Self { let row: (#(#field_ty,)*) = Queryable::build(row); Self { #(#build_expr,)* } } } }, )) }