@@ -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 ! { } ;
@@ -1618,35 +1629,20 @@ impl FieldCodegen<'_> for FieldData {
16181629 self . annotations ( ) . accessor_kind ( ) . unwrap_or ( accessor_kind) ;
16191630
16201631 // Collect field attributes from multiple sources
1621- let mut all_field_attributes = Vec :: new ( ) ;
1622-
1623- // 1. Get attributes from field annotations (/// <div rustbindgen attribute="..."></div>)
1624- all_field_attributes
1625- . extend ( self . annotations ( ) . attributes ( ) . iter ( ) . cloned ( ) ) ;
1626-
1627- // 2. Get custom attributes from callbacks
1628- all_field_attributes. extend ( ctx. options ( ) . all_callbacks ( |cb| {
1629- cb. field_attributes ( & FieldAttributeInfo {
1630- type_name : & parent_item. canonical_name ( ctx) ,
1631- type_kind : if parent. is_union ( ) {
1632- DeriveTypeKind :: Union
1633- } else {
1634- DeriveTypeKind :: Struct
1635- } ,
1636- field_name,
1637- field_type_name : field_ty. name ( ) ,
1638- } )
1639- } ) ) ;
1640-
1641- // 3. Get attributes from CLI/Builder patterns
16421632 let type_name = parent_item. canonical_name ( ctx) ;
1643- for ( type_pat, field_pat, attr) in & ctx. options ( ) . field_attr_patterns {
1644- if type_pat. as_ref ( ) == type_name &&
1645- field_pat. as_ref ( ) == field_name
1646- {
1647- all_field_attributes. push ( attr. to_string ( ) ) ;
1648- }
1649- }
1633+ let type_kind = if parent. is_union ( ) {
1634+ DeriveTypeKind :: Union
1635+ } else {
1636+ DeriveTypeKind :: Struct
1637+ } ;
1638+ let all_field_attributes = collect_field_attributes (
1639+ ctx,
1640+ self . annotations ( ) ,
1641+ & type_name,
1642+ type_kind,
1643+ field_name,
1644+ field_ty. name ( ) ,
1645+ ) ;
16501646
16511647 // Apply all custom attributes to the field
16521648 for attr in & all_field_attributes {
0 commit comments