Skip to content
This repository was archived by the owner on Mar 4, 2024. It is now read-only.

Commit 7e4399c

Browse files
committed
glib-macros: use a common gen_enum_from_glib fn
Signed-off-by: Marc-André Lureau <[email protected]>
1 parent 398e243 commit 7e4399c

File tree

3 files changed

+54
-49
lines changed

3 files changed

+54
-49
lines changed

Diff for: glib-macros/src/genum_derive.rs

+19-23
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,9 @@ use proc_macro_error::abort_call_site;
66
use quote::{format_ident, quote, quote_spanned};
77
use syn::{punctuated::Punctuated, spanned::Spanned, token::Comma, Data, Ident, Variant};
88

9-
use crate::utils::{crate_ident_new, parse_item_attributes, parse_type_name, ItemAttribute};
10-
11-
// Generate i32 to enum mapping, used to implement glib::translate::FromGlib<i32>, such as:
12-
// if value == Animal::Goat as i32 {
13-
// return Animal::Goat;
14-
// }
15-
fn gen_from_glib(enum_name: &Ident, enum_variants: &Punctuated<Variant, Comma>) -> TokenStream {
16-
// FIXME: can we express this with a match()?
17-
let recurse = enum_variants.iter().map(|v| {
18-
let name = &v.ident;
19-
quote_spanned! {v.span()=>
20-
if value == #enum_name::#name as i32 {
21-
return #enum_name::#name;
22-
}
23-
}
24-
});
25-
quote! {
26-
#(#recurse)*
27-
}
28-
}
9+
use crate::utils::{
10+
crate_ident_new, gen_enum_from_glib, parse_item_attributes, parse_type_name, ItemAttribute,
11+
};
2912

3013
// Generate glib::gobject_ffi::GEnumValue structs mapping the enum such as:
3114
// glib::gobject_ffi::GEnumValue {
@@ -100,7 +83,7 @@ pub fn impl_genum(input: &syn::DeriveInput) -> TokenStream {
10083
),
10184
};
10285
let get_type = format_ident!("{}_get_type", name.to_string().to_snake_case());
103-
let from_glib = gen_from_glib(name, enum_variants);
86+
let from_glib = gen_enum_from_glib(name, enum_variants);
10487
let (genum_values, nb_genum_values) = gen_genum_values(name, enum_variants);
10588

10689
quote! {
@@ -112,10 +95,23 @@ pub fn impl_genum(input: &syn::DeriveInput) -> TokenStream {
11295
}
11396
}
11497

98+
impl #crate_ident::translate::TryFromGlib<i32> for #name {
99+
type Error = i32;
100+
101+
fn try_from_glib(value: i32) -> Result<Self, i32> {
102+
let from_glib = || {
103+
#from_glib
104+
};
105+
106+
from_glib().ok_or(value)
107+
}
108+
}
109+
115110
impl #crate_ident::translate::FromGlib<i32> for #name {
116111
unsafe fn from_glib(value: i32) -> Self {
117-
#from_glib
118-
unreachable!();
112+
use #crate_ident::translate::TryFromGlib;
113+
114+
Self::try_from_glib(value).unwrap()
119115
}
120116
}
121117

Diff for: glib-macros/src/gerror_domain_derive.rs

+4-24
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,10 @@
22

33
use proc_macro2::TokenStream;
44
use proc_macro_error::abort_call_site;
5-
use quote::{quote, quote_spanned};
6-
use syn::{punctuated::Punctuated, spanned::Spanned, token::Comma, Data, Ident, Variant};
5+
use quote::quote;
6+
use syn::Data;
77

8-
use crate::utils::{crate_ident_new, parse_name};
9-
10-
// FIXME: merge with genum version
11-
fn gen_enum_from_glib(
12-
enum_name: &Ident,
13-
enum_variants: &Punctuated<Variant, Comma>,
14-
) -> TokenStream {
15-
// FIXME: can we express this with a match()?
16-
let recurse = enum_variants.iter().map(|v| {
17-
let name = &v.ident;
18-
quote_spanned! {v.span()=>
19-
if code == #enum_name::#name as i32 {
20-
return Some(#enum_name::#name);
21-
}
22-
}
23-
});
24-
quote! {
25-
#(#recurse)*
26-
}
27-
}
8+
use crate::utils::{crate_ident_new, gen_enum_from_glib, parse_name};
289

2910
pub fn impl_gerror_domain(input: &syn::DeriveInput) -> TokenStream {
3011
let name = &input.ident;
@@ -61,12 +42,11 @@ pub fn impl_gerror_domain(input: &syn::DeriveInput) -> TokenStream {
6142
self as i32
6243
}
6344

64-
fn from(code: i32) -> Option<Self>
45+
fn from(value: i32) -> Option<Self>
6546
where
6647
Self: Sized
6748
{
6849
#from_glib
69-
None
7050
}
7151
}
7252
}

Diff for: glib-macros/src/utils.rs

+31-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
// Take a look at the license at the top of the repository in the LICENSE file.
22

33
use anyhow::{bail, Result};
4-
use proc_macro2::{Ident, Span};
4+
use proc_macro2::{Ident, Span, TokenStream};
55
use proc_macro_crate::crate_name;
6-
use syn::{Attribute, DeriveInput, Lit, Meta, MetaList, NestedMeta};
6+
use quote::{quote, quote_spanned};
7+
use syn::{
8+
punctuated::Punctuated, spanned::Spanned, token::Comma, Attribute, DeriveInput, Lit, Meta,
9+
MetaList, NestedMeta, Variant,
10+
};
711

812
// find the #[@attr_name] attribute in @attrs
913
pub fn find_attribute_meta(attrs: &[Attribute], attr_name: &str) -> Result<Option<MetaList>> {
@@ -156,3 +160,28 @@ pub fn crate_ident_new() -> Ident {
156160

157161
Ident::new(&crate_name, Span::call_site())
158162
}
163+
164+
// Generate i32 to enum mapping, used to implement
165+
// glib::translate::TryFromGlib<i32>, such as:
166+
//
167+
// if value == Animal::Goat as i32 {
168+
// return Some(Animal::Goat);
169+
// }
170+
pub fn gen_enum_from_glib(
171+
enum_name: &Ident,
172+
enum_variants: &Punctuated<Variant, Comma>,
173+
) -> TokenStream {
174+
// FIXME: can we express this with a match()?
175+
let recurse = enum_variants.iter().map(|v| {
176+
let name = &v.ident;
177+
quote_spanned! { v.span() =>
178+
if value == #enum_name::#name as i32 {
179+
return Some(#enum_name::#name);
180+
}
181+
}
182+
});
183+
quote! {
184+
#(#recurse)*
185+
None
186+
}
187+
}

0 commit comments

Comments
 (0)