forked from diesel-rs/diesel
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathqueryable.rs
More file actions
52 lines (42 loc) · 1.48 KB
/
Copy pathqueryable.rs
File metadata and controls
52 lines (42 loc) · 1.48 KB
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
use quote::Tokens;
use syn;
use model::Model;
use util::wrap_item_in_const;
pub fn derive_queryable(item: syn::DeriveInput) -> Tokens {
let model = t!(Model::from_item(&item, "Queryable"));
let generics = syn::aster::from_generics(model.generics.clone())
.ty_param_id("__DB")
.ty_param_id("__ST")
.build();
let struct_ty = &model.ty;
let row_ty = model.attrs.iter().map(|a| &a.ty);
let row_ty = quote!((#(#row_ty,)*));
let build_expr = build_expr_for_model(&model);
let model_name_uppercase = model.name.as_ref().to_uppercase();
let dummy_const = format!("_IMPL_QUERYABLE_FOR_{}", model_name_uppercase).into();
wrap_item_in_const(
dummy_const,
quote!(
impl#generics diesel::Queryable<__ST, __DB> for #struct_ty where
__DB: diesel::backend::Backend + diesel::types::HasSqlType<__ST>,
#row_ty: diesel::Queryable<__ST, __DB>,
{
type Row = <#row_ty as diesel::Queryable<__ST, __DB>>::Row;
fn build(row: Self::Row) -> Self {
let row: #row_ty = diesel::Queryable::build(row);
#build_expr
}
}
),
)
}
fn build_expr_for_model(model: &Model) -> Tokens {
let attr_exprs = model.attrs.iter().map(|attr| {
let name = attr.field_name();
let idx = &attr.field_position;
quote!(#name: row.#idx)
});
quote!(Self {
#(#attr_exprs,)*
})
}