@@ -6,9 +6,20 @@ use proc_macro_error::abort_call_site;
6
6
use quote:: { quote, quote_spanned} ;
7
7
use syn:: { punctuated:: Punctuated , spanned:: Spanned , token:: Comma , Data , Ident , Variant } ;
8
8
9
- use crate :: utils:: {
10
- crate_ident_new, gen_enum_from_glib, parse_item_attributes, parse_name, ItemAttribute ,
11
- } ;
9
+ use crate :: utils:: { crate_ident_new, gen_enum_from_glib} ;
10
+
11
+ #[ derive( deluxe:: ExtractAttributes , Default ) ]
12
+ #[ deluxe( attributes( enum_type) ) ]
13
+ struct EnumType {
14
+ name : String ,
15
+ }
16
+
17
+ #[ derive( deluxe:: ExtractAttributes , Default ) ]
18
+ #[ deluxe( attributes( enum_value) , default ) ]
19
+ struct EnumValue {
20
+ name : Option < String > ,
21
+ nick : Option < String > ,
22
+ }
12
23
13
24
// Generate glib::gobject_ffi::GEnumValue structs mapping the enum such as:
14
25
// glib::gobject_ffi::GEnumValue {
@@ -18,35 +29,24 @@ use crate::utils::{
18
29
// },
19
30
fn gen_enum_values (
20
31
enum_name : & Ident ,
21
- enum_variants : & Punctuated < Variant , Comma > ,
32
+ enum_variants : & mut Punctuated < Variant , Comma > ,
33
+ errors : & deluxe:: Errors ,
22
34
) -> ( TokenStream , usize ) {
23
35
let crate_ident = crate_ident_new ( ) ;
24
36
25
37
// start at one as GEnumValue array is null-terminated
26
38
let mut n = 1 ;
27
- let recurse = enum_variants. iter ( ) . map ( |v| {
28
- let name = & v. ident ;
29
- let mut value_name = name. to_string ( ) . to_upper_camel_case ( ) ;
30
- let mut value_nick = name. to_string ( ) . to_kebab_case ( ) ;
31
-
32
- let attrs = parse_item_attributes ( "enum_value" , & v. attrs ) ;
33
- let attrs = match attrs {
34
- Ok ( attrs) => attrs,
35
- Err ( e) => abort_call_site ! (
36
- "{}: derive(glib::Enum) enum supports only the following optional attributes: #[enum_value(name = \" The Cat\" , nick = \" chat\" )]" ,
37
- e
38
- ) ,
39
- } ;
40
-
41
- attrs. into_iter ( ) . for_each ( |attr|
42
- match attr {
43
- ItemAttribute :: Name ( n) => value_name = n,
44
- ItemAttribute :: Nick ( n) => value_nick = n,
45
- }
46
- ) ;
39
+ let recurse = enum_variants. iter_mut ( ) . map ( |v| {
40
+ let EnumValue {
41
+ name : value_name,
42
+ nick : value_nick,
43
+ } = deluxe:: extract_attributes_optional ( v, errors) ;
47
44
48
- let value_name = format ! ( "{value_name}\0 " ) ;
49
- let value_nick = format ! ( "{value_nick}\0 " ) ;
45
+ let name = & v. ident ;
46
+ let mut value_name = value_name. unwrap_or_else ( || name. to_string ( ) . to_upper_camel_case ( ) ) ;
47
+ let mut value_nick = value_nick. unwrap_or_else ( || name. to_string ( ) . to_kebab_case ( ) ) ;
48
+ value_name. push ( '\0' ) ;
49
+ value_nick. push ( '\0' ) ;
50
50
51
51
n += 1 ;
52
52
quote_spanned ! { v. span( ) =>
@@ -65,28 +65,27 @@ fn gen_enum_values(
65
65
)
66
66
}
67
67
68
- pub fn impl_enum ( input : & syn:: DeriveInput ) -> TokenStream {
69
- let name = & input. ident ;
70
-
71
- let enum_variants = match input. data {
72
- Data :: Enum ( ref e) => & e. variants ,
68
+ pub fn impl_enum ( mut input : syn:: DeriveInput ) -> TokenStream {
69
+ let enum_variants = match & mut input. data {
70
+ Data :: Enum ( e) => & mut e. variants ,
73
71
_ => abort_call_site ! ( "#[derive(glib::Enum)] only supports enums" ) ,
74
72
} ;
75
73
76
- let gtype_name = match parse_name ( input, "enum_type" ) {
77
- Ok ( name) => name,
78
- Err ( e) => abort_call_site ! (
79
- "{}: #[derive(glib::Enum)] requires #[enum_type(name = \" EnumTypeName\" )]" ,
80
- e
81
- ) ,
82
- } ;
74
+ let errors = deluxe:: Errors :: new ( ) ;
75
+ let EnumType {
76
+ name : mut gtype_name,
77
+ } = deluxe:: extract_attributes_optional ( & mut input. attrs , & errors) ;
78
+ gtype_name. push ( '\0' ) ;
83
79
80
+ let name = & input. ident ;
84
81
let from_glib = gen_enum_from_glib ( name, enum_variants) ;
85
- let ( enum_values, nb_enum_values) = gen_enum_values ( name, enum_variants) ;
82
+ let ( enum_values, nb_enum_values) = gen_enum_values ( name, enum_variants, & errors ) ;
86
83
87
84
let crate_ident = crate_ident_new ( ) ;
88
85
89
86
quote ! {
87
+ #errors
88
+
90
89
impl #crate_ident:: translate:: IntoGlib for #name {
91
90
type GlibType = i32 ;
92
91
@@ -175,9 +174,11 @@ pub fn impl_enum(input: &syn::DeriveInput) -> TokenStream {
175
174
} ,
176
175
] ;
177
176
178
- let name = :: std:: ffi:: CString :: new( #gtype_name) . expect( "CString::new failed" ) ;
179
177
unsafe {
180
- let type_ = #crate_ident:: gobject_ffi:: g_enum_register_static( name. as_ptr( ) , VALUES . as_ptr( ) ) ;
178
+ let type_ = #crate_ident:: gobject_ffi:: g_enum_register_static(
179
+ #gtype_name. as_ptr( ) as * const _,
180
+ VALUES . as_ptr( ) ,
181
+ ) ;
181
182
let type_: #crate_ident:: Type = #crate_ident:: translate:: from_glib( type_) ;
182
183
assert!( type_. is_valid( ) ) ;
183
184
TYPE = type_;
0 commit comments