atmosphere_macros/derive/
bindings.rs1use proc_macro2::TokenStream;
2use quote::quote;
3use syn::Ident;
4
5use crate::schema::table::Table;
6
7pub fn bindings(table: &Table) -> TokenStream {
8 let col = Ident::new("col", proc_macro2::Span::call_site());
9 let query = Ident::new("query", proc_macro2::Span::call_site());
10
11 let mut binds = TokenStream::new();
12
13 {
14 let field = &table.primary_key.name.field();
15
16 binds.extend(quote!(
17 if #col.field() == Self::PRIMARY_KEY.field {
18 use ::atmosphere::Bindable;
19 return Ok(#query.dyn_bind(&self.#field));
20 }
21 ));
22 }
23
24 for fk in &table.foreign_keys {
25 let field = fk.name.field();
26
27 binds.extend(quote!(
28 if #col.field() == stringify!(#field) {
29 use ::atmosphere::Bindable;
30 return Ok(#query.dyn_bind(&self.#field));
31 }
32 ));
33 }
34
35 for data in &table.data_columns {
36 let field = data.name.field();
37
38 if data.modifiers.json {
39 binds.extend(quote!(
40 if #col.field() == stringify!(#field) {
41 use ::atmosphere::Bindable;
42 use ::atmosphere::sqlx::types::Json;
43 return Ok(#query.dyn_bind(Json(&self.#field)));
44 }
45 ));
46 } else {
47 binds.extend(quote!(
48 if #col.field() == stringify!(#field) {
49 use ::atmosphere::Bindable;
50 return Ok(#query.dyn_bind(&self.#field));
51 }
52 ));
53 }
54 }
55
56 for ts in &table.timestamp_columns {
57 let field = ts.name.field();
58
59 binds.extend(quote!(
60 if #col.field() == stringify!(#field) {
61 use ::atmosphere::Bindable;
62 return Ok(#query.dyn_bind(&self.#field));
63 }
64 ));
65 }
66
67 let ident = &table.ident;
68
69 quote!(
70 #[automatically_derived]
71 impl ::atmosphere::Bind for #ident {
72 fn bind<
73 'q,
74 Q: ::atmosphere::Bindable<'q>
75 >(
76 &'q self,
77 #col: &'q ::atmosphere::Column<Self>,
78 #query: Q
79 ) -> ::atmosphere::Result<Q> {
80 #binds
81
82 Err(::atmosphere::Error::Bind(
83 ::atmosphere::bind::BindError::Unknown(#col.field())
84 ))
85 }
86 }
87 )
88}