@@ -212,6 +212,40 @@ fn append_custom_derives<'a>(
212212 }
213213}
214214
215+ /// Collects field attributes from multiple sources (annotations, callbacks, and CLI/Builder patterns).
216+ fn collect_field_attributes (
217+ ctx : & BindgenContext ,
218+ annotations : & Annotations ,
219+ type_name : & str ,
220+ type_kind : DeriveTypeKind ,
221+ field_name : & str ,
222+ field_type_name : Option < & str > ,
223+ ) -> Vec < String > {
224+ let mut all_field_attributes = Vec :: new ( ) ;
225+
226+ // 1. Get attributes from annotations
227+ all_field_attributes. extend ( annotations. attributes ( ) . iter ( ) . cloned ( ) ) ;
228+
229+ // 2. Get custom attributes from callbacks
230+ all_field_attributes. extend ( ctx. options ( ) . all_callbacks ( |cb| {
231+ cb. field_attributes ( & FieldAttributeInfo {
232+ type_name,
233+ type_kind,
234+ field_name,
235+ field_type_name,
236+ } )
237+ } ) ) ;
238+
239+ // 3. Get attributes from CLI/Builder patterns
240+ for ( type_pat, field_pat, attr) in & ctx. options ( ) . field_attr_patterns {
241+ if type_pat. as_ref ( ) == type_name && field_pat. as_ref ( ) == field_name {
242+ all_field_attributes. push ( attr. to_string ( ) ) ;
243+ }
244+ }
245+
246+ all_field_attributes
247+ }
248+
215249impl From < DerivableTraits > for Vec < & ' static str > {
216250 fn from ( derivable_traits : DerivableTraits ) -> Vec < & ' static str > {
217251 [
@@ -1139,39 +1173,16 @@ impl CodeGenerator for Type {
11391173 . unwrap_or ( ctx. options ( ) . default_visibility ) ;
11401174 let access_spec = access_specifier ( visibility) ;
11411175
1142- // Collect field attributes from multiple sources for newtype tuple field
1143- let mut all_field_attributes = Vec :: new ( ) ;
1144-
1145- // 1. Get attributes from typedef annotations (if any)
1146- all_field_attributes. extend (
1147- item. annotations ( ) . attributes ( ) . iter ( ) . cloned ( ) ,
1148- ) ;
1149-
1150- // 2. Get custom attributes from callbacks
1151- all_field_attributes. extend (
1152- ctx. options ( ) . all_callbacks ( |cb| {
1153- cb. field_attributes ( & FieldAttributeInfo {
1154- type_name : & item. canonical_name ( ctx) ,
1155- type_kind : DeriveTypeKind :: Struct ,
1156- field_name : "0" ,
1157- field_type_name : inner_item
1158- . expect_type ( )
1159- . name ( ) ,
1160- } )
1161- } ) ,
1162- ) ;
1163-
1164- // 3. Get attributes from CLI/Builder patterns
1176+ // Collect field attributes for newtype tuple field
11651177 let type_name = item. canonical_name ( ctx) ;
1166- for ( type_pat, field_pat, attr) in
1167- & ctx. options ( ) . field_attr_patterns
1168- {
1169- if type_pat. as_ref ( ) == type_name &&
1170- field_pat. as_ref ( ) == "0"
1171- {
1172- all_field_attributes. push ( attr. to_string ( ) ) ;
1173- }
1174- }
1178+ let all_field_attributes = collect_field_attributes (
1179+ ctx,
1180+ item. annotations ( ) ,
1181+ & type_name,
1182+ DeriveTypeKind :: Struct ,
1183+ "0" ,
1184+ inner_item. expect_type ( ) . name ( ) ,
1185+ ) ;
11751186
11761187 // Build the field with attributes
11771188 let mut field_tokens = quote ! { } ;
@@ -1630,35 +1641,20 @@ impl FieldCodegen<'_> for FieldData {
16301641 self . annotations ( ) . accessor_kind ( ) . unwrap_or ( accessor_kind) ;
16311642
16321643 // Collect field attributes from multiple sources
1633- let mut all_field_attributes = Vec :: new ( ) ;
1634-
1635- // 1. Get attributes from field annotations (/// <div rustbindgen attribute="..."></div>)
1636- all_field_attributes
1637- . extend ( self . annotations ( ) . attributes ( ) . iter ( ) . cloned ( ) ) ;
1638-
1639- // 2. Get custom attributes from callbacks
1640- all_field_attributes. extend ( ctx. options ( ) . all_callbacks ( |cb| {
1641- cb. field_attributes ( & FieldAttributeInfo {
1642- type_name : & parent_item. canonical_name ( ctx) ,
1643- type_kind : if parent. is_union ( ) {
1644- DeriveTypeKind :: Union
1645- } else {
1646- DeriveTypeKind :: Struct
1647- } ,
1648- field_name,
1649- field_type_name : field_ty. name ( ) ,
1650- } )
1651- } ) ) ;
1652-
1653- // 3. Get attributes from CLI/Builder patterns
16541644 let type_name = parent_item. canonical_name ( ctx) ;
1655- for ( type_pat, field_pat, attr) in & ctx. options ( ) . field_attr_patterns {
1656- if type_pat. as_ref ( ) == type_name &&
1657- field_pat. as_ref ( ) == field_name
1658- {
1659- all_field_attributes. push ( attr. to_string ( ) ) ;
1660- }
1661- }
1645+ let type_kind = if parent. is_union ( ) {
1646+ DeriveTypeKind :: Union
1647+ } else {
1648+ DeriveTypeKind :: Struct
1649+ } ;
1650+ let all_field_attributes = collect_field_attributes (
1651+ ctx,
1652+ self . annotations ( ) ,
1653+ & type_name,
1654+ type_kind,
1655+ field_name,
1656+ field_ty. name ( ) ,
1657+ ) ;
16621658
16631659 // Apply all custom attributes to the field
16641660 for attr in & all_field_attributes {
0 commit comments