@@ -23,10 +23,22 @@ pub enum ModelType {
23
23
#[ darling( forward_attrs( allow, doc, cfg) , supports( struct_named) ) ]
24
24
pub struct ModelOpts {
25
25
pub ident : syn:: Ident ,
26
+ pub generics : syn:: Generics ,
26
27
pub data : darling:: ast:: Data < darling:: util:: Ignored , FieldOpts > ,
27
28
}
28
29
29
30
impl ModelOpts {
31
+ pub fn new_from_derive_input ( input : & syn:: DeriveInput ) -> Result < Self , darling:: error:: Error > {
32
+ let opts = Self :: from_derive_input ( input) ?;
33
+ if !opts. generics . params . is_empty ( ) {
34
+ return Err (
35
+ darling:: Error :: custom ( "generics in models are not supported" )
36
+ . with_span ( & opts. generics ) ,
37
+ ) ;
38
+ }
39
+ Ok ( opts)
40
+ }
41
+
30
42
/// Get the fields of the struct.
31
43
///
32
44
/// # Panics
@@ -79,10 +91,11 @@ impl ModelOpts {
79
91
}
80
92
81
93
#[ derive( Debug , Clone , FromField ) ]
82
- #[ darling( attributes( form ) ) ]
94
+ #[ darling( attributes( model ) ) ]
83
95
pub struct FieldOpts {
84
96
pub ident : Option < syn:: Ident > ,
85
97
pub ty : syn:: Type ,
98
+ pub unique : darling:: util:: Flag ,
86
99
}
87
100
88
101
impl FieldOpts {
@@ -108,6 +121,7 @@ impl FieldOpts {
108
121
auto_value : is_auto,
109
122
primary_key : is_primary_key,
110
123
null : false ,
124
+ unique : self . unique . is_present ( ) ,
111
125
}
112
126
}
113
127
}
@@ -136,4 +150,89 @@ pub struct Field {
136
150
pub auto_value : bool ,
137
151
pub primary_key : bool ,
138
152
pub null : bool ,
153
+ pub unique : bool ,
154
+ }
155
+
156
+ #[ cfg( test) ]
157
+ mod tests {
158
+ use syn:: parse_quote;
159
+
160
+ use super :: * ;
161
+
162
+ #[ test]
163
+ fn model_args_default ( ) {
164
+ let args: ModelArgs = Default :: default ( ) ;
165
+ assert_eq ! ( args. model_type, ModelType :: Application ) ;
166
+ assert ! ( args. table_name. is_none( ) ) ;
167
+ }
168
+
169
+ #[ test]
170
+ fn model_type_default ( ) {
171
+ let model_type: ModelType = Default :: default ( ) ;
172
+ assert_eq ! ( model_type, ModelType :: Application ) ;
173
+ }
174
+
175
+ #[ test]
176
+ fn model_opts_fields ( ) {
177
+ let input: syn:: DeriveInput = parse_quote ! {
178
+ struct TestModel {
179
+ id: i32 ,
180
+ name: String ,
181
+ }
182
+ } ;
183
+ let opts = ModelOpts :: new_from_derive_input ( & input) . unwrap ( ) ;
184
+ let fields = opts. fields ( ) ;
185
+ assert_eq ! ( fields. len( ) , 2 ) ;
186
+ assert_eq ! ( fields[ 0 ] . ident. as_ref( ) . unwrap( ) . to_string( ) , "id" ) ;
187
+ assert_eq ! ( fields[ 1 ] . ident. as_ref( ) . unwrap( ) . to_string( ) , "name" ) ;
188
+ }
189
+
190
+ #[ test]
191
+ fn model_opts_as_model ( ) {
192
+ let input: syn:: DeriveInput = parse_quote ! {
193
+ struct TestModel {
194
+ id: i32 ,
195
+ name: String ,
196
+ }
197
+ } ;
198
+ let opts = ModelOpts :: new_from_derive_input ( & input) . unwrap ( ) ;
199
+ let args = ModelArgs :: default ( ) ;
200
+ let model = opts. as_model ( & args) . unwrap ( ) ;
201
+ assert_eq ! ( model. name. to_string( ) , "TestModel" ) ;
202
+ assert_eq ! ( model. table_name, "test_model" ) ;
203
+ assert_eq ! ( model. fields. len( ) , 2 ) ;
204
+ assert_eq ! ( model. field_count( ) , 2 ) ;
205
+ }
206
+
207
+ #[ test]
208
+ fn model_opts_as_model_migration ( ) {
209
+ let input: syn:: DeriveInput = parse_quote ! {
210
+ #[ model( model_type = "migration" ) ]
211
+ struct TestModel {
212
+ id: i32 ,
213
+ name: String ,
214
+ }
215
+ } ;
216
+ let opts = ModelOpts :: new_from_derive_input ( & input) . unwrap ( ) ;
217
+ let args = ModelArgs :: from_meta ( & input. attrs . first ( ) . unwrap ( ) . meta ) . unwrap ( ) ;
218
+ let err = opts. as_model ( & args) . unwrap_err ( ) ;
219
+ assert_eq ! (
220
+ err. to_string( ) ,
221
+ "migration model names must start with an underscore"
222
+ ) ;
223
+ }
224
+
225
+ #[ test]
226
+ fn field_opts_as_field ( ) {
227
+ let input: syn:: Field = parse_quote ! {
228
+ #[ model( unique) ]
229
+ name: String
230
+ } ;
231
+ let field_opts = FieldOpts :: from_field ( & input) . unwrap ( ) ;
232
+ let field = field_opts. as_field ( ) ;
233
+ assert_eq ! ( field. field_name. to_string( ) , "name" ) ;
234
+ assert_eq ! ( field. column_name, "name" ) ;
235
+ assert_eq ! ( field. ty, parse_quote!( String ) ) ;
236
+ assert ! ( field. unique) ;
237
+ }
139
238
}
0 commit comments