File: identifiable.rs

package info (click to toggle)
rust-diesel-derives 1.4.0-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 288 kB
  • sloc: makefile: 2
file content (50 lines) | stat: -rw-r--r-- 1,481 bytes parent folder | download
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
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 = &model.name;
    let table_name = model.table_name();

    let (impl_generics, ty_generics, where_clause) = item.generics.split_for_impl();
    let mut ref_generics = item.generics.clone();
    ref_generics.params.push(parse_quote!('ident));
    let (ref_generics, ..) = ref_generics.split_for_impl();

    let (field_ty, field_access): (Vec<_>, Vec<_>) = model
        .primary_key_names
        .iter()
        .filter_map(|pk| model.find_column(pk).emit_error())
        .map(|f| (&f.ty, f.name.access()))
        .unzip();

    Ok(wrap_in_dummy_mod(
        model.dummy_mod_name("identifiable"),
        quote! {
            use diesel::associations::{HasTable, Identifiable};

            impl #impl_generics HasTable for #struct_name #ty_generics
            #where_clause
            {
                type Table = #table_name::table;

                fn table() -> Self::Table {
                    #table_name::table
                }
            }

            impl #ref_generics Identifiable for &'ident #struct_name #ty_generics
            #where_clause
            {
                type Id = (#(&'ident #field_ty),*);

                fn id(self) -> Self::Id {
                    (#(&self#field_access),*)
                }
            }
        },
    ))
}