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