@@ -11,13 +11,22 @@ extern crate quote;
11
11
type TokenStream = proc_macro:: TokenStream ;
12
12
13
13
use proc_macro2:: Span ;
14
- use syn:: Ident ;
15
14
use syn:: {
16
15
parse:: { Parse , ParseStream , Result } ,
17
16
punctuated:: Punctuated ,
18
- token, Attribute ,
17
+ token, Attribute , Ident ,
19
18
} ;
20
19
20
+ trait IdentExt {
21
+ fn append ( & self , string : & str ) -> Ident ;
22
+ }
23
+
24
+ impl IdentExt for syn:: Ident {
25
+ fn append ( & self , string : & str ) -> Ident {
26
+ Ident :: new ( & format ! ( "{}{}" , self , string) , self . span ( ) )
27
+ }
28
+ }
29
+
21
30
#[ derive( Debug ) ]
22
31
struct Struct {
23
32
pub attrs : Vec < Attribute > ,
@@ -67,14 +76,18 @@ impl Field {
67
76
}
68
77
}
69
78
70
- fn optional ( & self ) -> bool {
71
- let mut ret = false ;
79
+ fn ty ( & self ) -> proc_macro2:: TokenStream {
80
+ let ty = & self . ty ;
81
+
82
+ let mut ty_tokens = quote ! ( #ty) ;
83
+
72
84
self . walk_attrs ( & mut |ref ident| {
73
85
if * ident == "optional" {
74
- ret = true ;
86
+ ty_tokens = quote ! ( Option <#ty> ) ;
75
87
}
76
88
} ) ;
77
- ret
89
+
90
+ ty_tokens
78
91
}
79
92
80
93
fn fk ( & self ) -> bool {
@@ -124,6 +137,18 @@ struct Schema {
124
137
pub schema : syn:: Path ,
125
138
}
126
139
140
+ impl Schema {
141
+ fn sql_type ( & self ) -> proc_macro2:: TokenStream {
142
+ let schema = & self . schema ;
143
+ quote ! ( #schema:: SqlType )
144
+ }
145
+
146
+ fn table ( & self ) -> proc_macro2:: TokenStream {
147
+ let schema = & self . schema ;
148
+ quote ! ( #schema:: table)
149
+ }
150
+ }
151
+
127
152
struct Table {
128
153
pub table_token : Ident ,
129
154
pub assignment_token : Token ! [ =] ,
@@ -166,110 +191,82 @@ struct Parsed {
166
191
}
167
192
168
193
impl Parsed {
169
- fn gen_model_with_id_fields ( & self ) -> Vec < proc_macro2:: TokenStream > {
194
+ fn model_with_id_fields ( & self ) -> Vec < proc_macro2:: TokenStream > {
170
195
let mut fields = Vec :: new ( ) ;
171
196
fields. push ( quote ! ( pub id: i32 ) ) ;
172
197
173
198
let model_name = & self . input . ident ;
174
-
175
199
let model_name_lower = Ident :: new ( & self . input . camel_to_snake ( ) , Span :: call_site ( ) ) ;
176
200
177
- let model_with_id_model_field = quote ! ( pub #model_name_lower: #model_name) ;
178
-
179
- fields. push ( model_with_id_model_field) ;
201
+ fields. push ( quote ! ( pub #model_name_lower: #model_name) ) ;
180
202
181
203
self . input . fields . iter ( ) . for_each ( |field| {
182
204
if field. fk ( ) {
183
- let ty = & field. ty ;
205
+ let ty = field. ty ( ) ;
184
206
let name = & field. name ;
185
-
186
- if field. optional ( ) {
187
- fields. push ( quote ! ( pub #name: Option <#ty>) ) ;
188
- } else {
189
- fields. push ( quote ! ( pub #name: #ty) ) ;
190
- }
207
+ fields. push ( quote ! ( pub #name: #ty) ) ;
191
208
}
192
209
} ) ;
193
210
fields
194
211
}
195
212
196
- fn gen_model_with_id_ident ( & self ) -> Ident {
197
- Ident :: new ( & format ! ( "{}WithId" , self . input. ident) , Span :: call_site ( ) )
213
+ fn model_with_id_ident ( & self ) -> Ident {
214
+ self . input . ident . append ( "WithId" )
198
215
}
199
216
200
- fn gen_model_with_id ( & self ) -> proc_macro2:: TokenStream {
201
- let model_with_id = self . gen_model_with_id_ident ( ) ;
202
- let table_name = & self . attr . table . table ;
203
- let model_with_id_fields = self . gen_model_with_id_fields ( ) ;
217
+ fn model_with_id ( & self ) -> proc_macro2:: TokenStream {
218
+ let model_with_id = self . model_with_id_ident ( ) ;
219
+ let table = & self . attr . table . table ;
220
+ let fields = self . model_with_id_fields ( ) ;
204
221
205
222
quote_spanned ! { Span :: call_site( ) =>
206
223
#[ derive( Serialize , Deserialize , FromSqlRow , Associations , Identifiable , Debug , PartialEq ) ]
207
- #[ table_name = #table_name]
208
-
224
+ #[ table_name = #table]
209
225
pub struct #model_with_id {
210
- #( #model_with_id_fields , ) *
226
+ #( #fields , ) *
211
227
}
212
228
}
213
229
}
214
230
215
- fn gen_model_fields ( & self ) -> Vec < proc_macro2:: TokenStream > {
231
+ fn model_fields ( & self ) -> Vec < proc_macro2:: TokenStream > {
216
232
let mut fields = Vec :: new ( ) ;
217
233
self . input . fields . iter ( ) . for_each ( |field| {
218
234
if !field. fk ( ) {
219
- let ty = & field. ty ;
235
+ let ty = field. ty ( ) ;
220
236
let name = & field. name ;
221
-
222
- if field. optional ( ) {
223
- fields. push ( quote ! ( pub #name: Option <#ty>) ) ;
224
- } else {
225
- fields. push ( quote ! ( pub #name: #ty) ) ;
226
- }
237
+ fields. push ( quote ! ( pub #name: #ty) ) ;
227
238
}
228
239
} ) ;
229
240
fields
230
241
}
231
242
232
- fn gen_model ( & self ) -> proc_macro2:: TokenStream {
233
- let model_name = & self . input . ident ;
234
- let model_fields = self . gen_model_fields ( ) ;
235
- let table_name = & self . attr . table . table ;
243
+ fn model ( & self ) -> proc_macro2:: TokenStream {
244
+ let model = & self . input . ident ;
245
+ let fields = self . model_fields ( ) ;
246
+ let table = & self . attr . table . table ;
236
247
237
248
quote_spanned ! { Span :: call_site( ) =>
238
249
#[ derive( Serialize , Deserialize , FromSqlRow , Insertable , AsChangeset , Debug , PartialEq ) ]
239
- #[ table_name = #table_name ]
240
- pub struct #model_name {
241
- #( #model_fields , ) *
250
+ #[ table_name = #table ]
251
+ pub struct #model {
252
+ #( #fields , ) *
242
253
}
243
254
}
244
255
}
245
256
246
- fn gen_table ( & self ) -> proc_macro2:: TokenStream {
247
- let schema = & self . attr . schema . schema ;
248
- quote_spanned ! ( Span :: call_site( ) => #schema:: table)
249
- }
250
-
251
- fn gen_sql_type ( & self ) -> proc_macro2:: TokenStream {
252
- let schema = & self . attr . schema . schema ;
253
- quote_spanned ! ( Span :: call_site( ) => #schema:: SqlType )
254
- }
255
-
256
- fn gen_queryable_row ( & self ) -> proc_macro2:: TokenStream {
257
+ fn queryable_row ( & self ) -> proc_macro2:: TokenStream {
257
258
let mut fields = Vec :: new ( ) ;
258
259
fields. push ( quote ! ( i32 ) ) ;
259
260
260
261
self . input . fields . iter ( ) . for_each ( |field| {
261
- let ty = & field. ty ;
262
- if field. optional ( ) {
263
- fields. push ( quote ! ( Option <#ty>) ) ;
264
- } else {
265
- fields. push ( quote ! ( #ty) ) ;
266
- }
262
+ let ty = field. ty ( ) ;
263
+ fields. push ( quote ! ( #ty) ) ;
267
264
} ) ;
268
265
269
- quote_spanned ! ( Span :: call_site ( ) => type Row = ( #( #fields, ) * ) ; )
266
+ quote ! ( type Row = ( #( #fields, ) * ) ; )
270
267
}
271
268
272
- fn gen_queryable_inner_fields ( & self ) -> Vec < proc_macro2:: TokenStream > {
269
+ fn queryable_inner_fields ( & self ) -> Vec < proc_macro2:: TokenStream > {
273
270
let mut fields = Vec :: new ( ) ;
274
271
let mut inner_fields = Vec :: new ( ) ;
275
272
@@ -309,9 +306,9 @@ impl Parsed {
309
306
fields
310
307
}
311
308
312
- fn gen_queryable_fields ( & self ) -> proc_macro2:: TokenStream {
313
- let fields = self . gen_queryable_inner_fields ( ) ;
314
- let model_with_id = self . gen_model_with_id_ident ( ) ;
309
+ fn queryable_fields ( & self ) -> proc_macro2:: TokenStream {
310
+ let fields = self . queryable_inner_fields ( ) ;
311
+ let model_with_id = self . model_with_id_ident ( ) ;
315
312
316
313
quote ! {
317
314
#model_with_id {
@@ -320,11 +317,11 @@ impl Parsed {
320
317
}
321
318
}
322
319
323
- fn gen_queryable_impl ( & self ) -> proc_macro2:: TokenStream {
324
- let fields = self . gen_queryable_fields ( ) ;
325
- let model_with_id = self . gen_model_with_id_ident ( ) ;
326
- let sql_type = self . gen_sql_type ( ) ;
327
- let row = self . gen_queryable_row ( ) ;
320
+ fn queryable_impl ( & self ) -> proc_macro2:: TokenStream {
321
+ let fields = self . queryable_fields ( ) ;
322
+ let model_with_id = self . model_with_id_ident ( ) ;
323
+ let sql_type = self . attr . schema . sql_type ( ) ;
324
+ let row = self . queryable_row ( ) ;
328
325
329
326
quote_spanned ! { Span :: call_site( ) =>
330
327
impl diesel:: Queryable <#sql_type, diesel:: pg:: Pg > for #model_with_id {
@@ -338,12 +335,12 @@ impl Parsed {
338
335
339
336
fn gen_resource_controller ( & self ) -> proc_macro2:: TokenStream {
340
337
let model = & self . input . ident ;
341
- let model_with_id = self . gen_model_with_id_ident ( ) ;
342
- let controller = Ident :: new ( & format ! ( "{}Controller" , & self . input. ident) , Span :: call_site ( ) ) ;
343
- let table = self . gen_table ( ) ;
344
- let sql_type = self . gen_sql_type ( ) ;
338
+ let model_with_id = self . model_with_id_ident ( ) ;
339
+ let controller = & self . input . ident . append ( "Controller" ) ;
340
+ let table = self . attr . schema . table ( ) ;
341
+ let sql_type = self . attr . schema . sql_type ( ) ;
345
342
346
- quote_spanned ! { Span :: call_site ( ) =>
343
+ quote ! {
347
344
pub struct #controller;
348
345
349
346
impl ResourceDB for #controller { }
@@ -499,10 +496,10 @@ pub fn resource(attr: TokenStream, input: TokenStream) -> TokenStream {
499
496
500
497
let parsed = Parsed { attr : parsed_attr, input : parsed_struct } ;
501
498
502
- let model_with_id = parsed. gen_model_with_id ( ) ;
503
- let model = parsed. gen_model ( ) ;
499
+ let model_with_id = parsed. model_with_id ( ) ;
500
+ let model = parsed. model ( ) ;
504
501
let resource_controller = parsed. gen_resource_controller ( ) ;
505
- let queryable = parsed. gen_queryable_impl ( ) ;
502
+ let queryable = parsed. queryable_impl ( ) ;
506
503
507
504
let generated = quote_spanned ! { Span :: call_site( ) =>
508
505
#model_with_id
0 commit comments