@@ -103,6 +103,7 @@ pub fn derive_godot_class(item: venial::Item) -> ParseResult<TokenStream> {
103103 class_name,
104104 & struct_cfg. base_ty ,
105105 struct_cfg. is_tool ,
106+ struct_cfg. icon . as_ref ( ) ,
106107 & fields. all_fields ,
107108 ) ;
108109
@@ -146,6 +147,13 @@ pub fn derive_godot_class(item: venial::Item) -> ParseResult<TokenStream> {
146147 modifiers. push ( quote ! { with_tool } )
147148 }
148149
150+ // Handle icon separately since it takes an argument (can't use the modifiers pattern).
151+ let icon_modifier = if let Some ( icon) = & struct_cfg. icon {
152+ quote ! { . with_icon( #icon) }
153+ } else {
154+ TokenStream :: new ( )
155+ } ;
156+
149157 // Declares a "funcs collection" struct that, for holds a constant for each #[func].
150158 // That constant maps the Rust name (constant ident) to the Godot registered name (string value).
151159 let funcs_collection_struct_name = format_funcs_collection_struct ( class_name) ;
@@ -198,7 +206,7 @@ pub fn derive_godot_class(item: venial::Item) -> ParseResult<TokenStream> {
198206 #struct_docs_registration
199207 :: godot:: sys:: plugin_add!( #prv:: __GODOT_PLUGIN_REGISTRY; #prv:: ClassPlugin :: new:: <#class_name>(
200208 #prv:: PluginItem :: Struct (
201- #prv:: Struct :: new:: <#class_name>( ) #( . #modifiers( ) ) *
209+ #prv:: Struct :: new:: <#class_name>( ) #( . #modifiers( ) ) * #icon_modifier
202210 )
203211 ) ) ;
204212
@@ -303,6 +311,7 @@ struct ClassAttributes {
303311 is_tool : bool ,
304312 is_internal : bool ,
305313 rename : Option < Ident > ,
314+ icon : Option < TokenStream > ,
306315 deprecations : Vec < TokenStream > ,
307316}
308317
@@ -421,6 +430,7 @@ fn make_user_class_impl(
421430 class_name : & Ident ,
422431 trait_base_class : & Ident ,
423432 is_tool : bool ,
433+ icon : Option < & TokenStream > ,
424434 all_fields : & [ Field ] ,
425435) -> ( TokenStream , bool ) {
426436 #[ cfg( feature = "codegen-full" ) ]
@@ -480,12 +490,19 @@ fn make_user_class_impl(
480490 None
481491 } ;
482492
493+ let icon = if let Some ( expr) = icon {
494+ quote ! { Some ( #expr) }
495+ } else {
496+ quote ! { None }
497+ } ;
498+
483499 let user_class_impl = quote ! {
484500 impl :: godot:: obj:: UserClass for #class_name {
485501 #[ doc( hidden) ]
486502 fn __config( ) -> :: godot:: private:: ClassConfig {
487503 :: godot:: private:: ClassConfig {
488504 is_tool: #is_tool,
505+ icon: #icon,
489506 }
490507 }
491508
@@ -510,6 +527,7 @@ fn parse_struct_attributes(class: &venial::Struct) -> ParseResult<ClassAttribute
510527 let mut is_tool = false ;
511528 let mut is_internal = false ;
512529 let mut rename: Option < Ident > = None ;
530+ let mut icon: Option < TokenStream > = None ;
513531 let mut deprecations = vec ! [ ] ;
514532
515533 // #[class] attribute on struct
@@ -542,6 +560,11 @@ fn parse_struct_attributes(class: &venial::Struct) -> ParseResult<ClassAttribute
542560 // #[class(rename = NewName)]
543561 rename = parser. handle_ident ( "rename" ) ?;
544562
563+ // #[class(icon = "PATH")]
564+ if let Some ( expr) = parser. handle_expr ( "icon" ) ? {
565+ icon = Some ( expr) ;
566+ }
567+
545568 // #[class(internal)]
546569 // Named "internal" following Godot terminology: https://github.com/godotengine/godot-cpp/blob/master/include/godot_cpp/core/class_db.hpp#L327
547570 if parser. handle_alone ( "internal" ) ? {
@@ -583,6 +606,7 @@ fn parse_struct_attributes(class: &venial::Struct) -> ParseResult<ClassAttribute
583606 is_tool,
584607 is_internal,
585608 rename,
609+ icon,
586610 deprecations,
587611 } )
588612}
0 commit comments