Skip to content

Commit

Permalink
glib-macros: support higher level types on ValueDelegate
Browse files Browse the repository at this point in the history
  • Loading branch information
SeaDve committed Mar 6, 2023
1 parent b8ed5b5 commit b93d961
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 5 deletions.
16 changes: 11 additions & 5 deletions glib-macros/src/value_delegate_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ pub fn impl_value_delegate(input: ValueDelegateInput) -> syn::Result<proc_macro:

// this must be called in a context where `this` is defined.
let delegate_value = match mode {
DeriveMode::From => quote!(#delegated_ty::from(this)),
DeriveMode::From => {
quote!(<#delegated_ty as std::convert::From<_>>::from(this))
}
DeriveMode::Private => quote!(this.0),
};

Expand All @@ -142,14 +144,18 @@ pub fn impl_value_delegate(input: ValueDelegateInput) -> syn::Result<proc_macro:
});

let from_value = match mode {
DeriveMode::From => quote!(#ident::from(#delegated_ty::from_value(value))),
DeriveMode::Private => quote!(#ident(#delegated_ty::from_value(value))),
DeriveMode::From => {
quote!(#ident::from(<#delegated_ty as #crate_ident::value::FromValue<'a>>::from_value(value)))
}
DeriveMode::Private => {
quote!(#ident(<#delegated_ty as #crate_ident::value::FromValue<'a>>::from_value(value)))
}
};

let res = quote! {
impl #crate_ident::types::StaticType for #ident {
fn static_type() -> glib::types::Type {
#delegated_ty::static_type()
<#delegated_ty as #crate_ident::types::StaticType>::static_type()
}
}
impl #crate_ident::value::ToValue for #ident {
Expand Down Expand Up @@ -179,7 +185,7 @@ pub fn impl_value_delegate(input: ValueDelegateInput) -> syn::Result<proc_macro:
type BuilderFn = <#delegated_ty as #crate_ident::HasParamSpec>::BuilderFn;

fn param_spec_builder() -> Self::BuilderFn {
#delegated_ty::param_spec_builder()
<#delegated_ty as #crate_ident::HasParamSpec>::param_spec_builder()
}
}
};
Expand Down
73 changes: 73 additions & 0 deletions glib-macros/tests/value_delegate_derive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use glib::{value::FromValue, HasParamSpec, StaticType, ToValue};

#[test]
fn higher_level_types() {
#[derive(Debug, glib::ValueDelegate)]
pub struct MyVec(Vec<String>);

#[derive(Debug, glib::ValueDelegate)]
#[value_delegate(from = Option<String>)]
struct MyVecManualFrom(Vec<String>);

impl From<Option<String>> for MyVecManualFrom {
fn from(v: Option<String>) -> Self {
Self(v.into_iter().collect::<Vec<_>>())
}
}
impl<'a> From<&'a MyVecManualFrom> for Option<String> {
fn from(v: &'a MyVecManualFrom) -> Self {
v.0.iter().next().cloned()
}
}

let vec = vec!["foo".to_string(), "bar".to_string()];
let vec_value = vec.to_value();
let my_vec_value = MyVec(vec.clone()).to_value();

assert_eq!(MyVec::static_type(), Vec::<String>::static_type());
assert_eq!(
vec_value.get::<Vec<String>>().unwrap(),
my_vec_value.get::<Vec<String>>().unwrap(),
);
assert_eq!(vec_value.value_type(), my_vec_value.value_type());
assert_eq!(unsafe { Vec::<String>::from_value(&vec_value) }, unsafe {
MyVec::from_value(&vec_value).0
});
assert_eq!(
unsafe { Vec::<String>::from_value(&my_vec_value) },
unsafe { MyVec::from_value(&my_vec_value).0 }
);

let opt = Some("foo".to_string());
let opt_value = opt.to_value();
let my_vec_manual_from_value = MyVecManualFrom::from(opt).to_value();

assert_eq!(
MyVecManualFrom::static_type(),
Option::<String>::static_type()
);
assert_eq!(
opt_value.get::<Option<String>>().unwrap(),
my_vec_manual_from_value.get::<Option<String>>().unwrap(),
);
assert_eq!(
opt_value.value_type(),
my_vec_manual_from_value.value_type()
);
assert_eq!(
unsafe {
Option::<String>::from_value(&opt_value)
.into_iter()
.collect::<Vec<_>>()
},
unsafe { MyVecManualFrom::from_value(&opt_value).0 }
);
assert_eq!(
unsafe {
Option::<String>::from_value(&my_vec_manual_from_value)
.into_iter()
.collect::<Vec<_>>()
},
unsafe { MyVecManualFrom::from_value(&my_vec_manual_from_value).0 }
);
}

0 comments on commit b93d961

Please sign in to comment.