Skip to content

Commit

Permalink
Implement ext trait on IsA<T>, don't generate overridden methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ranfdev committed Oct 13, 2023
1 parent d1fdc2e commit 797ba7d
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 72 deletions.
30 changes: 10 additions & 20 deletions glib-macros/src/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ fn expand_impl_getset_properties(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
let ident = name_to_ident(name);
let ty = &p.ty;

let getter = p.get.is_some().then(|| {
let getter = (p.get.is_some() && p.override_class.is_none() && p.override_interface.is_none() ).then(|| {
let span = p.attrs_span;
parse_quote_spanned!(span=>
#[must_use]
Expand All @@ -573,7 +573,7 @@ fn expand_impl_getset_properties(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
})
});

let setter = (p.set.is_some() && !p.is_construct_only).then(|| {
let setter = (p.set.is_some() && p.override_class.is_none() && p.override_interface.is_none() && !p.is_construct_only).then(|| {
let ident = format_ident!("set_{}", ident);
let target_ty = quote!(<<#ty as #crate_ident::Property>::Value as #crate_ident::HasParamSpec>::SetValue);
let set_ty = if p.nullable {
Expand Down Expand Up @@ -618,7 +618,7 @@ fn expand_impl_connect_prop_notify(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
connection_fns.collect::<Vec<_>>()
}

fn expand_impl_notify_prop(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
fn expand_impl_notify_prop(wrapper_type: &syn::Path, props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
let crate_ident = crate_ident_new();
let emit_fns = props.iter().map(|p| -> syn::ImplItemFn {
let name = strip_raw_prefix_from_name(&p.name);
Expand All @@ -627,7 +627,7 @@ fn expand_impl_notify_prop(props: &[PropDesc]) -> Vec<syn::ImplItemFn> {
let enum_ident = name_to_enum_ident(name.value());
parse_quote_spanned!(span=> pub fn #fn_ident(&self) {
self.notify_by_pspec(
&<<Self as #crate_ident::object::ObjectSubclassIs>::Subclass
&<<#wrapper_type as #crate_ident::object::ObjectSubclassIs>::Subclass
as #crate_ident::subclass::object::DerivedObjectProperties>::derived_properties()
[DerivedPropertiesEnum::#enum_ident as usize]
);
Expand Down Expand Up @@ -692,7 +692,7 @@ pub fn impl_derive_props(input: PropsMacroInput) -> TokenStream {
let fn_set_property = expand_set_property_fn(&input.props);
let getset_properties = expand_impl_getset_properties(&input.props);
let connect_prop_notify = expand_impl_connect_prop_notify(&input.props);
let notify_prop = expand_impl_notify_prop(&input.props);
let notify_prop = expand_impl_notify_prop(&wrapper_type, &input.props);
let properties_enum = expand_properties_enum(&input.props);

let rust_interface = if let Some(ext_trait) = input.ext_trait {
Expand All @@ -704,17 +704,7 @@ pub fn impl_derive_props(input: PropsMacroInput) -> TokenStream {
wrapper_type.segments.last().unwrap().ident
)
};
let signatures = getset_properties
.iter()
.chain(connect_prop_notify.iter())
.chain(notify_prop.iter())
.map(|item| &item.sig);
let trait_def = quote! {
pub trait #trait_ident {
#(#signatures;)*
}
};
let impls = getset_properties
let fns_without_visibility_modifier = getset_properties
.into_iter()
.chain(connect_prop_notify)
.chain(notify_prop)
Expand All @@ -723,10 +713,10 @@ pub fn impl_derive_props(input: PropsMacroInput) -> TokenStream {
item
});
quote! {
#trait_def
impl #trait_ident for #wrapper_type {
#(#impls)*
pub trait #trait_ident: #crate_ident::IsA<#wrapper_type> {
#(#fns_without_visibility_modifier)*
}
impl<T: #crate_ident::IsA<#wrapper_type>> #trait_ident for T {}
}
} else {
quote! {
Expand All @@ -740,7 +730,7 @@ pub fn impl_derive_props(input: PropsMacroInput) -> TokenStream {
};

let expanded = quote! {
use #crate_ident::{PropertyGet, PropertySet, ToValue};
use #crate_ident::{PropertyGet, PropertySet, ToValue, Cast};

#properties_enum

Expand Down
60 changes: 8 additions & 52 deletions glib-macros/tests/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ mod base {
use super::*;

#[derive(Properties, Default)]
#[properties(wrapper_type = super::Base)]
#[properties(wrapper_type = super::Base, ext_trait)]
pub struct Base {
#[property(get = Self::not_overridden)]
overridden: PhantomData<u32>,
Expand Down Expand Up @@ -388,59 +388,15 @@ fn props() {
);
}

mod ext_trait {
use glib::subclass::object::DerivedObjectProperties;
use glib::ObjectExt;

use glib::subclass::{prelude::ObjectImpl, types::ObjectSubclass};
use glib_macros::Properties;
use std::cell::RefCell;

pub mod imp {
use super::*;

#[derive(Properties, Default)]
#[properties(wrapper_type = super::Author, ext_trait)]
pub struct Author {
#[property(get, set)]
firstname: RefCell<String>,
#[property(get, set)]
lastname: RefCell<String>,
}

#[glib::derived_properties]
impl ObjectImpl for Author {}

#[glib::object_subclass]
impl ObjectSubclass for Author {
const NAME: &'static str = "Author";
type Type = super::Author;
}
}

glib::wrapper! {
pub struct Author(ObjectSubclass<imp::Author>);
}
impl Author {
pub fn new() -> Self {
glib::Object::builder().build()
}
}
impl Default for Author {
fn default() -> Self {
Self::new()
}
}
}

#[test]
fn ext_trait() {
use ext_trait::imp::AuthorPropertiesExt;
let author = ext_trait::Author::new();
AuthorPropertiesExt::set_firstname(&author, "John");
AuthorPropertiesExt::set_lastname(&author, "Doe");
assert_eq!(AuthorPropertiesExt::firstname(&author), "John");
assert_eq!(AuthorPropertiesExt::lastname(&author), "Doe");
use base::imp::BasePropertiesExt;
let base: base::Base = glib::object::Object::builder().build();
assert_eq!(BasePropertiesExt::overridden(&base), 42);

let foo: foo::Foo = glib::object::Object::builder().build();
assert_eq!(BasePropertiesExt::overridden(&foo), 43);
assert_eq!(foo.overridden(), 43);
}

#[test]
Expand Down

0 comments on commit 797ba7d

Please sign in to comment.