@@ -20,8 +20,9 @@ pub fn derive_godot_class(item: venial::Item) -> ParseResult<TokenStream> {
20
20
. as_struct ( )
21
21
. ok_or_else ( || venial:: Error :: new ( "Not a valid struct" ) ) ?;
22
22
23
+ let named_fields = named_fields ( class) ?;
23
24
let struct_cfg = parse_struct_attributes ( class) ?;
24
- let fields = parse_fields ( class , struct_cfg. init_strategy ) ?;
25
+ let fields = parse_fields ( named_fields , struct_cfg. init_strategy ) ?;
25
26
26
27
let class_name = & class. name ;
27
28
let class_name_str: String = struct_cfg
@@ -292,9 +293,6 @@ fn parse_struct_attributes(class: &venial::Struct) -> ParseResult<ClassAttribute
292
293
base_ty = base;
293
294
}
294
295
295
- // #[class(rename = NewName)]
296
- rename = parser. handle_ident ( "rename" ) ?;
297
-
298
296
// #[class(init)], #[class(no_init)]
299
297
match handle_opposite_keys ( & mut parser, "init" , "class" ) ? {
300
298
Some ( true ) => init_strategy = InitStrategy :: Generated ,
@@ -314,20 +312,25 @@ fn parse_struct_attributes(class: &venial::Struct) -> ParseResult<ClassAttribute
314
312
is_editor_plugin = true ;
315
313
316
314
// Requires #[class(tool, base=EditorPlugin)].
317
- if !is_tool {
315
+ // The base=EditorPlugin check should come first to create the best compile errors since it's more complex to resolve.
316
+ // See https://github.com/godot-rust/gdext/pull/773
317
+ if base_ty != ident ( "EditorPlugin" ) {
318
318
return bail ! (
319
319
attr_key,
320
- "#[class(editor_plugin)] requires additional key `tool `"
320
+ "#[class(editor_plugin)] requires additional key-value `base=EditorPlugin `"
321
321
) ;
322
322
}
323
- if base_ty != ident ( "EditorPlugin" ) {
323
+ if !is_tool {
324
324
return bail ! (
325
325
attr_key,
326
- "#[class(editor_plugin)] requires additional key-value `base=EditorPlugin `"
326
+ "#[class(editor_plugin)] requires additional key `tool `"
327
327
) ;
328
328
}
329
329
}
330
330
331
+ // #[class(rename = NewName)]
332
+ rename = parser. handle_ident ( "rename" ) ?;
333
+
331
334
// #[class(hidden)]
332
335
// TODO consider naming this "internal"; godot-cpp uses that terminology:
333
336
// https://github.com/godotengine/godot-cpp/blob/master/include/godot_cpp/core/class_db.hpp#L327
@@ -349,22 +352,30 @@ fn parse_struct_attributes(class: &venial::Struct) -> ParseResult<ClassAttribute
349
352
} )
350
353
}
351
354
352
- /// Returns field names and 1 base field, if available
353
- fn parse_fields ( class : & venial:: Struct , init_strategy : InitStrategy ) -> ParseResult < Fields > {
354
- let mut all_fields = vec ! [ ] ;
355
- let mut base_field = Option :: < Field > :: None ;
356
- let mut has_deprecated_base = false ;
357
-
358
- let named_fields: Vec < ( venial:: NamedField , Punct ) > = match & class. fields {
359
- venial:: Fields :: Unit => {
360
- vec ! [ ]
361
- }
355
+ /// Fetches data for all named fields for a struct.
356
+ ///
357
+ /// Errors if `class` is a tuple struct.
358
+ fn named_fields ( class : & venial:: Struct ) -> ParseResult < Vec < ( venial:: NamedField , Punct ) > > {
359
+ // This is separate from parse_fields to improve compile errors. The errors from here demand larger and more non-local changes from the API
360
+ // user than those from parse_struct_attributes, so this must be run first.
361
+ match & class. fields {
362
+ venial:: Fields :: Unit => Ok ( vec ! [ ] ) ,
362
363
venial:: Fields :: Tuple ( _) => bail ! (
363
364
& class. fields,
364
365
"#[derive(GodotClass)] not supported for tuple structs" ,
365
366
) ?,
366
- venial:: Fields :: Named ( fields) => fields. fields . inner . clone ( ) ,
367
- } ;
367
+ venial:: Fields :: Named ( fields) => Ok ( fields. fields . inner . clone ( ) ) ,
368
+ }
369
+ }
370
+
371
+ /// Returns field names and 1 base field, if available.
372
+ fn parse_fields (
373
+ named_fields : Vec < ( venial:: NamedField , Punct ) > ,
374
+ init_strategy : InitStrategy ,
375
+ ) -> ParseResult < Fields > {
376
+ let mut all_fields = vec ! [ ] ;
377
+ let mut base_field = Option :: < Field > :: None ;
378
+ let mut has_deprecated_base = false ;
368
379
369
380
// Attributes on struct fields
370
381
for ( named_field, _punct) in named_fields {
0 commit comments