Skip to content

Commit ce3c69e

Browse files
authored
Merge pull request #1370 from felinira/fina/empty-properties
glib-macros/properties: Allow structs with no properties
2 parents 4bc38db + 7cb805a commit ce3c69e

File tree

2 files changed

+67
-26
lines changed

2 files changed

+67
-26
lines changed

glib-macros/src/properties.rs

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,6 @@ impl Parse for PropsMacroInput {
8585
))
8686
}
8787
};
88-
if props.is_empty() {
89-
return Err(syn::Error::new(
90-
proc_macro2::Span::call_site(),
91-
"Struct must have at least one field with the #[property(…)] attribute",
92-
));
93-
}
9488
Ok(Self {
9589
wrapper_ty: attrs.wrapper_ty,
9690
ext_trait: attrs.ext_trait,
@@ -513,6 +507,7 @@ fn expand_set_property_fn(props: &[PropDesc]) -> TokenStream2 {
513507
})
514508
});
515509
quote!(
510+
#[allow(unreachable_code)]
516511
fn derived_set_property(&self,
517512
id: usize,
518513
value: &#crate_ident::Value,
@@ -662,29 +657,43 @@ fn name_to_enum_ident(name: String) -> syn::Ident {
662657
}
663658

664659
fn expand_properties_enum(props: &[PropDesc]) -> TokenStream2 {
665-
let properties: Vec<syn::Ident> = props
666-
.iter()
667-
.map(|p| {
668-
let name: String = p.name.value();
660+
if props.is_empty() {
661+
quote! {
662+
#[derive(Debug, Copy, Clone)]
663+
enum DerivedPropertiesEnum {}
664+
impl std::convert::TryFrom<usize> for DerivedPropertiesEnum {
665+
type Error = usize;
669666

670-
name_to_enum_ident(name)
671-
})
672-
.collect();
673-
let props = properties.iter();
674-
let indices = 0..properties.len();
675-
quote! {
676-
#[repr(usize)]
677-
#[derive(Debug, Copy, Clone)]
678-
enum DerivedPropertiesEnum {
679-
#(#props,)*
667+
fn try_from(item: usize) -> ::core::result::Result<Self, <Self as std::convert::TryFrom<usize>>::Error> {
668+
::core::result::Result::Err(item)
669+
}
670+
}
680671
}
681-
impl std::convert::TryFrom<usize> for DerivedPropertiesEnum {
682-
type Error = usize;
672+
} else {
673+
let properties: Vec<syn::Ident> = props
674+
.iter()
675+
.map(|p| {
676+
let name: String = p.name.value();
683677

684-
fn try_from(item: usize) -> ::core::result::Result<Self, <Self as std::convert::TryFrom<usize>>::Error> {
685-
match item {
686-
#(#indices => ::core::result::Result::Ok(Self::#properties),)*
687-
_ => ::core::result::Result::Err(item)
678+
name_to_enum_ident(name)
679+
})
680+
.collect();
681+
let props = properties.iter();
682+
let indices = 0..properties.len();
683+
quote! {
684+
#[repr(usize)]
685+
#[derive(Debug, Copy, Clone)]
686+
enum DerivedPropertiesEnum {
687+
#(#props,)*
688+
}
689+
impl std::convert::TryFrom<usize> for DerivedPropertiesEnum {
690+
type Error = usize;
691+
692+
fn try_from(item: usize) -> ::core::result::Result<Self, <Self as std::convert::TryFrom<usize>>::Error> {
693+
match item {
694+
#(#indices => ::core::result::Result::Ok(Self::#properties),)*
695+
_ => ::core::result::Result::Err(item)
696+
}
688697
}
689698
}
690699
}

glib-macros/tests/properties.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,3 +504,35 @@ fn keyword_propnames() {
504504
mykwnames.set_property("try", 255_u8);
505505
assert_eq!(mykwnames.r#try(), 255_u8);
506506
}
507+
508+
/// This struct is intentionally left empty.
509+
///
510+
/// Ensure the code compiles even when no properties are specified at all.
511+
/// This is useful for refactoring.
512+
#[test]
513+
#[allow(unreachable_code)]
514+
fn empty() {
515+
mod empty {
516+
mod imp {
517+
use glib::subclass::prelude::*;
518+
use glib_macros::Properties;
519+
520+
#[derive(Properties, Default)]
521+
#[properties(wrapper_type = super::Empty)]
522+
pub struct Empty {}
523+
524+
#[glib::object_subclass]
525+
impl ObjectSubclass for Empty {
526+
const NAME: &'static str = "Empty";
527+
type Type = super::Empty;
528+
}
529+
530+
#[glib::derived_properties]
531+
impl ObjectImpl for Empty {}
532+
}
533+
534+
glib::wrapper! {
535+
pub struct Empty(ObjectSubclass<imp::Empty>);
536+
}
537+
}
538+
}

0 commit comments

Comments
 (0)