@@ -9,7 +9,10 @@ use syn::{
9
9
Variant ,
10
10
} ;
11
11
12
- use crate :: utils:: { crate_ident_new, gen_enum_from_glib, parse_nested_meta_items, NestedMetaItem } ;
12
+ use crate :: utils:: {
13
+ crate_ident_new, gen_enum_from_glib, parse_nested_meta_items, parse_optional_nested_meta_items,
14
+ NestedMetaItem ,
15
+ } ;
13
16
14
17
// generates glib::gobject_ffi::GEnumValue structs mapping the enum such as:
15
18
// glib::gobject_ffi::GEnumValue {
@@ -70,6 +73,7 @@ pub fn impl_enum(input: &syn::DeriveInput) -> TokenStream {
70
73
Data :: Enum ( ref e) => & e. variants ,
71
74
_ => abort_call_site ! ( "#[derive(glib::Enum)] only supports enums" ) ,
72
75
} ;
76
+ let ( g_enum_values, nb_enum_values) = gen_enum_values ( name, enum_variants) ;
73
77
74
78
let mut gtype_name = NestedMetaItem :: < syn:: LitStr > :: new ( "name" )
75
79
. required ( )
@@ -84,13 +88,152 @@ pub fn impl_enum(input: &syn::DeriveInput) -> TokenStream {
84
88
Ok ( attr) => attr,
85
89
} ;
86
90
let gtype_name = gtype_name. value . unwrap ( ) ;
87
- let from_glib = gen_enum_from_glib ( name, enum_variants) ;
88
- let ( enum_values, nb_enum_values) = gen_enum_values ( name, enum_variants) ;
91
+
92
+ let mut plugin_type = NestedMetaItem :: < syn:: Path > :: new ( "plugin_type" ) . value_required ( ) ;
93
+ let mut lazy_registration =
94
+ NestedMetaItem :: < syn:: LitBool > :: new ( "lazy_registration" ) . value_required ( ) ;
95
+
96
+ let found = parse_optional_nested_meta_items (
97
+ & input. attrs ,
98
+ "enum_dynamic" ,
99
+ & mut [ & mut plugin_type, & mut lazy_registration] ,
100
+ ) ;
89
101
90
102
let crate_ident = crate_ident_new ( ) ;
91
103
104
+ let register_enum = match found {
105
+ Err ( e) => return e. to_compile_error ( ) ,
106
+ Ok ( None ) => register_enum_as_static (
107
+ & crate_ident,
108
+ name,
109
+ gtype_name,
110
+ g_enum_values,
111
+ nb_enum_values,
112
+ ) ,
113
+ Ok ( Some ( _) ) => {
114
+ let plugin_ty = plugin_type
115
+ . value
116
+ . map ( |p| p. into_token_stream ( ) )
117
+ . unwrap_or ( quote ! ( #crate_ident:: TypeModule ) ) ;
118
+ let lazy_registration = lazy_registration. value . map ( |b| b. value ) . unwrap_or_default ( ) ;
119
+ register_enum_as_dynamic (
120
+ & crate_ident,
121
+ plugin_ty,
122
+ lazy_registration,
123
+ name,
124
+ gtype_name,
125
+ g_enum_values,
126
+ nb_enum_values,
127
+ )
128
+ }
129
+ } ;
130
+
131
+ let from_glib = gen_enum_from_glib ( name, enum_variants) ;
132
+
133
+ quote ! {
134
+ impl #crate_ident:: translate:: IntoGlib for #name {
135
+ type GlibType = i32 ;
136
+
137
+ #[ inline]
138
+ fn into_glib( self ) -> i32 {
139
+ self as i32
140
+ }
141
+ }
142
+
143
+ impl #crate_ident:: translate:: TryFromGlib <i32 > for #name {
144
+ type Error = i32 ;
145
+
146
+ #[ inline]
147
+ unsafe fn try_from_glib( value: i32 ) -> :: core:: result:: Result <Self , i32 > {
148
+ let from_glib = || {
149
+ #from_glib
150
+ } ;
151
+
152
+ from_glib( ) . ok_or( value)
153
+ }
154
+ }
155
+
156
+ impl #crate_ident:: translate:: FromGlib <i32 > for #name {
157
+ #[ inline]
158
+ unsafe fn from_glib( value: i32 ) -> Self {
159
+ use #crate_ident:: translate:: TryFromGlib ;
160
+
161
+ Self :: try_from_glib( value) . unwrap( )
162
+ }
163
+ }
164
+
165
+ impl #crate_ident:: value:: ValueType for #name {
166
+ type Type = Self ;
167
+ }
168
+
169
+ unsafe impl <' a> #crate_ident:: value:: FromValue <' a> for #name {
170
+ type Checker = #crate_ident:: value:: GenericValueTypeChecker <Self >;
171
+
172
+ #[ inline]
173
+ unsafe fn from_value( value: & ' a #crate_ident:: value:: Value ) -> Self {
174
+ #crate_ident:: translate:: from_glib( #crate_ident:: gobject_ffi:: g_value_get_enum(
175
+ #crate_ident:: translate:: ToGlibPtr :: to_glib_none( value) . 0
176
+ ) )
177
+ }
178
+ }
179
+
180
+ impl #crate_ident:: value:: ToValue for #name {
181
+ #[ inline]
182
+ fn to_value( & self ) -> #crate_ident:: value:: Value {
183
+ let mut value = #crate_ident:: value:: Value :: for_value_type:: <Self >( ) ;
184
+ unsafe {
185
+ #crate_ident:: gobject_ffi:: g_value_set_enum(
186
+ #crate_ident:: translate:: ToGlibPtrMut :: to_glib_none_mut( & mut value) . 0 ,
187
+ #crate_ident:: translate:: IntoGlib :: into_glib( * self )
188
+ )
189
+ }
190
+ value
191
+ }
192
+
193
+ #[ inline]
194
+ fn value_type( & self ) -> #crate_ident:: Type {
195
+ <Self as #crate_ident:: StaticType >:: static_type( )
196
+ }
197
+ }
198
+
199
+ impl :: std:: convert:: From <#name> for #crate_ident:: Value {
200
+ #[ inline]
201
+ fn from( v: #name) -> Self {
202
+ #crate_ident:: value:: ToValue :: to_value( & v)
203
+ }
204
+ }
205
+
206
+ impl #crate_ident:: StaticType for #name {
207
+ #[ inline]
208
+ fn static_type( ) -> #crate_ident:: Type {
209
+ Self :: register_enum( )
210
+ }
211
+ }
212
+
213
+ #register_enum
214
+
215
+ impl #crate_ident:: HasParamSpec for #name {
216
+ type ParamSpec = #crate_ident:: ParamSpecEnum ;
217
+ type SetValue = Self ;
218
+ type BuilderFn = fn ( & :: core:: primitive:: str , Self ) -> #crate_ident:: ParamSpecEnumBuilder <Self >;
219
+
220
+ fn param_spec_builder( ) -> Self :: BuilderFn {
221
+ |name, default_value| Self :: ParamSpec :: builder_with_default( name, default_value)
222
+ }
223
+ }
224
+ }
225
+ }
226
+
227
+ // Registers the enum as a static type.
228
+ fn register_enum_as_static (
229
+ crate_ident : & TokenStream ,
230
+ name : & Ident ,
231
+ gtype_name : syn:: LitStr ,
232
+ g_enum_values : TokenStream ,
233
+ nb_enum_values : usize ,
234
+ ) -> TokenStream {
92
235
// registers the enum on first use (lazy registration).
93
- let register_enum = quote ! {
236
+ quote ! {
94
237
impl #name {
95
238
/// Registers the enum only once.
96
239
#[ inline]
@@ -100,7 +243,7 @@ pub fn impl_enum(input: &syn::DeriveInput) -> TokenStream {
100
243
101
244
ONCE . call_once( || {
102
245
static mut VALUES : [ #crate_ident:: gobject_ffi:: GEnumValue ; #nb_enum_values] = [
103
- #enum_values
246
+ #g_enum_values
104
247
#crate_ident:: gobject_ffi:: GEnumValue {
105
248
value: 0 ,
106
249
value_name: :: std:: ptr:: null( ) ,
@@ -121,51 +264,20 @@ pub fn impl_enum(input: &syn::DeriveInput) -> TokenStream {
121
264
}
122
265
}
123
266
}
124
- } ;
125
-
126
- impl_enum_ ( name, from_glib, register_enum)
267
+ }
127
268
}
128
269
129
- pub fn impl_dynamic_enum ( input : & syn:: DeriveInput ) -> TokenStream {
130
- let name = & input. ident ;
131
-
132
- let enum_variants = match input. data {
133
- Data :: Enum ( ref e) => & e. variants ,
134
- _ => abort_call_site ! ( "#[derive(glib::Enum)] only supports enums" ) ,
135
- } ;
136
-
137
- let mut gtype_name = NestedMetaItem :: < syn:: LitStr > :: new ( "name" )
138
- . required ( )
139
- . value_required ( ) ;
140
- let mut plugin_type = NestedMetaItem :: < syn:: Path > :: new ( "plugin_type" ) . value_required ( ) ;
141
- let mut lazy_registration =
142
- NestedMetaItem :: < syn:: LitBool > :: new ( "lazy_registration" ) . value_required ( ) ;
143
- let found = parse_nested_meta_items (
144
- & input. attrs ,
145
- "enum_type" ,
146
- & mut [ & mut gtype_name, & mut plugin_type, & mut lazy_registration] ,
147
- ) ;
148
-
149
- match found {
150
- Ok ( None ) => {
151
- abort_call_site ! ( "#[derive(glib::DynamicEnum)] requires #[enum_type(name = \" EnumTypeName\" [, plugin_type = <subclass_of_glib::TypePlugin>][, lazy_registration = true|false])]" )
152
- }
153
- Err ( e) => return e. to_compile_error ( ) ,
154
- Ok ( attr) => attr,
155
- } ;
156
-
157
- let crate_ident = crate_ident_new ( ) ;
158
-
159
- let gtype_name = gtype_name. value . unwrap ( ) ;
160
- let plugin_ty = plugin_type
161
- . value
162
- . map ( |p| p. into_token_stream ( ) )
163
- . unwrap_or ( quote ! ( #crate_ident:: TypeModule ) ) ;
164
- let lazy_registration = lazy_registration. value . map ( |b| b. value ) . unwrap_or_default ( ) ;
165
-
166
- let from_glib = gen_enum_from_glib ( name, enum_variants) ;
167
- let ( g_enum_values, nb_enum_values) = gen_enum_values ( name, enum_variants) ;
168
-
270
+ // The following implementations follows the lifecycle of plugins and of dynamic types (see [`TypePluginExt`] and [`TypeModuleExt`]).
271
+ // An enum can be reregistered as a dynamic type.
272
+ fn register_enum_as_dynamic (
273
+ crate_ident : & TokenStream ,
274
+ plugin_ty : TokenStream ,
275
+ lazy_registration : bool ,
276
+ name : & Ident ,
277
+ gtype_name : syn:: LitStr ,
278
+ g_enum_values : TokenStream ,
279
+ nb_enum_values : usize ,
280
+ ) -> TokenStream {
169
281
// Wrap each GEnumValue to EnumValue
170
282
let g_enum_values_expr: ExprArray = parse_quote ! { [ #g_enum_values] } ;
171
283
let enum_values_iter = g_enum_values_expr. elems . iter ( ) . map ( |v| {
@@ -184,7 +296,7 @@ pub fn impl_dynamic_enum(input: &syn::DeriveInput) -> TokenStream {
184
296
185
297
// The following implementations follows the lifecycle of plugins and of dynamic types (see [`TypePluginExt`] and [`TypeModuleExt`]).
186
298
// An enum can be reregistered as a dynamic type.
187
- let register_enum_impl = if lazy_registration {
299
+ if lazy_registration {
188
300
// registers the enum as a dynamic type on the first use (lazy registration).
189
301
// a weak reference on the plugin is stored and will be used later on the first use of the enum.
190
302
// this implementation relies on a static storage of a weak reference on the plugin and of the GLib type to know if the enum has been registered.
@@ -309,108 +421,5 @@ pub fn impl_dynamic_enum(input: &syn::DeriveInput) -> TokenStream {
309
421
}
310
422
}
311
423
}
312
- } ;
313
-
314
- impl_enum_ ( name, from_glib, register_enum_impl)
315
- }
316
-
317
- pub fn impl_enum_ (
318
- name : & syn:: Ident ,
319
- from_glib : TokenStream ,
320
- register_enum : TokenStream ,
321
- ) -> TokenStream {
322
- let crate_ident = crate_ident_new ( ) ;
323
-
324
- quote ! {
325
- impl #crate_ident:: translate:: IntoGlib for #name {
326
- type GlibType = i32 ;
327
-
328
- #[ inline]
329
- fn into_glib( self ) -> i32 {
330
- self as i32
331
- }
332
- }
333
-
334
- impl #crate_ident:: translate:: TryFromGlib <i32 > for #name {
335
- type Error = i32 ;
336
-
337
- #[ inline]
338
- unsafe fn try_from_glib( value: i32 ) -> :: core:: result:: Result <Self , i32 > {
339
- let from_glib = || {
340
- #from_glib
341
- } ;
342
-
343
- from_glib( ) . ok_or( value)
344
- }
345
- }
346
-
347
- impl #crate_ident:: translate:: FromGlib <i32 > for #name {
348
- #[ inline]
349
- unsafe fn from_glib( value: i32 ) -> Self {
350
- use #crate_ident:: translate:: TryFromGlib ;
351
-
352
- Self :: try_from_glib( value) . unwrap( )
353
- }
354
- }
355
-
356
- impl #crate_ident:: value:: ValueType for #name {
357
- type Type = Self ;
358
- }
359
-
360
- unsafe impl <' a> #crate_ident:: value:: FromValue <' a> for #name {
361
- type Checker = #crate_ident:: value:: GenericValueTypeChecker <Self >;
362
-
363
- #[ inline]
364
- unsafe fn from_value( value: & ' a #crate_ident:: value:: Value ) -> Self {
365
- #crate_ident:: translate:: from_glib( #crate_ident:: gobject_ffi:: g_value_get_enum(
366
- #crate_ident:: translate:: ToGlibPtr :: to_glib_none( value) . 0
367
- ) )
368
- }
369
- }
370
-
371
- impl #crate_ident:: value:: ToValue for #name {
372
- #[ inline]
373
- fn to_value( & self ) -> #crate_ident:: value:: Value {
374
- let mut value = #crate_ident:: value:: Value :: for_value_type:: <Self >( ) ;
375
- unsafe {
376
- #crate_ident:: gobject_ffi:: g_value_set_enum(
377
- #crate_ident:: translate:: ToGlibPtrMut :: to_glib_none_mut( & mut value) . 0 ,
378
- #crate_ident:: translate:: IntoGlib :: into_glib( * self )
379
- )
380
- }
381
- value
382
- }
383
-
384
- #[ inline]
385
- fn value_type( & self ) -> #crate_ident:: Type {
386
- <Self as #crate_ident:: StaticType >:: static_type( )
387
- }
388
- }
389
-
390
- impl :: std:: convert:: From <#name> for #crate_ident:: Value {
391
- #[ inline]
392
- fn from( v: #name) -> Self {
393
- #crate_ident:: value:: ToValue :: to_value( & v)
394
- }
395
- }
396
-
397
- impl #crate_ident:: StaticType for #name {
398
- #[ inline]
399
- fn static_type( ) -> #crate_ident:: Type {
400
- Self :: register_enum( )
401
- }
402
- }
403
-
404
- #register_enum
405
-
406
- impl #crate_ident:: HasParamSpec for #name {
407
- type ParamSpec = #crate_ident:: ParamSpecEnum ;
408
- type SetValue = Self ;
409
- type BuilderFn = fn ( & :: core:: primitive:: str , Self ) -> #crate_ident:: ParamSpecEnumBuilder <Self >;
410
-
411
- fn param_spec_builder( ) -> Self :: BuilderFn {
412
- |name, default_value| Self :: ParamSpec :: builder_with_default( name, default_value)
413
- }
414
- }
415
424
}
416
425
}
0 commit comments