Skip to content

Commit 6bdbfe0

Browse files
authored
Merge pull request #1043 from SeaDve/value-delegate-improvements
Value delegate improvements
2 parents 27c7cd3 + b93d961 commit 6bdbfe0

File tree

2 files changed

+87
-8
lines changed

2 files changed

+87
-8
lines changed

glib-macros/src/value_delegate_derive.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ pub fn impl_value_delegate(input: ValueDelegateInput) -> syn::Result<proc_macro:
123123

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

@@ -132,7 +134,7 @@ pub fn impl_value_delegate(input: ValueDelegateInput) -> syn::Result<proc_macro:
132134
impl #crate_ident::value::ToValueOptional for #ident {
133135
fn to_value_optional(s: Option<&Self>) -> #crate_ident::value::Value {
134136
if let Some(this) = s {
135-
Some(&#delegate_value).to_value()
137+
#crate_ident::value::ToValue::to_value(&Some(&#delegate_value))
136138
} else {
137139
#crate_ident::value::ToValueOptional::to_value_optional(None::<&#delegated_ty>)
138140
}
@@ -142,24 +144,28 @@ pub fn impl_value_delegate(input: ValueDelegateInput) -> syn::Result<proc_macro:
142144
});
143145

144146
let from_value = match mode {
145-
DeriveMode::From => quote!(#ident::from(#delegated_ty::from_value(value))),
146-
DeriveMode::Private => quote!(#ident(#delegated_ty::from_value(value))),
147+
DeriveMode::From => {
148+
quote!(#ident::from(<#delegated_ty as #crate_ident::value::FromValue<'a>>::from_value(value)))
149+
}
150+
DeriveMode::Private => {
151+
quote!(#ident(<#delegated_ty as #crate_ident::value::FromValue<'a>>::from_value(value)))
152+
}
147153
};
148154

149155
let res = quote! {
150156
impl #crate_ident::types::StaticType for #ident {
151157
fn static_type() -> glib::types::Type {
152-
#delegated_ty::static_type()
158+
<#delegated_ty as #crate_ident::types::StaticType>::static_type()
153159
}
154160
}
155161
impl #crate_ident::value::ToValue for #ident {
156162
fn to_value(&self) -> #crate_ident::value::Value {
157163
let this = self;
158-
#delegate_value.to_value()
164+
#crate_ident::value::ToValue::to_value(&#delegate_value)
159165
}
160166
fn value_type(&self) -> #crate_ident::types::Type {
161167
let this = self;
162-
#delegate_value.value_type()
168+
#crate_ident::value::ToValue::value_type(&#delegate_value)
163169
}
164170
}
165171

@@ -179,7 +185,7 @@ pub fn impl_value_delegate(input: ValueDelegateInput) -> syn::Result<proc_macro:
179185
type BuilderFn = <#delegated_ty as #crate_ident::HasParamSpec>::BuilderFn;
180186

181187
fn param_spec_builder() -> Self::BuilderFn {
182-
#delegated_ty::param_spec_builder()
188+
<#delegated_ty as #crate_ident::HasParamSpec>::param_spec_builder()
183189
}
184190
}
185191
};
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use glib::{value::FromValue, HasParamSpec, StaticType, ToValue};
2+
3+
#[test]
4+
fn higher_level_types() {
5+
#[derive(Debug, glib::ValueDelegate)]
6+
pub struct MyVec(Vec<String>);
7+
8+
#[derive(Debug, glib::ValueDelegate)]
9+
#[value_delegate(from = Option<String>)]
10+
struct MyVecManualFrom(Vec<String>);
11+
12+
impl From<Option<String>> for MyVecManualFrom {
13+
fn from(v: Option<String>) -> Self {
14+
Self(v.into_iter().collect::<Vec<_>>())
15+
}
16+
}
17+
impl<'a> From<&'a MyVecManualFrom> for Option<String> {
18+
fn from(v: &'a MyVecManualFrom) -> Self {
19+
v.0.iter().next().cloned()
20+
}
21+
}
22+
23+
let vec = vec!["foo".to_string(), "bar".to_string()];
24+
let vec_value = vec.to_value();
25+
let my_vec_value = MyVec(vec.clone()).to_value();
26+
27+
assert_eq!(MyVec::static_type(), Vec::<String>::static_type());
28+
assert_eq!(
29+
vec_value.get::<Vec<String>>().unwrap(),
30+
my_vec_value.get::<Vec<String>>().unwrap(),
31+
);
32+
assert_eq!(vec_value.value_type(), my_vec_value.value_type());
33+
assert_eq!(unsafe { Vec::<String>::from_value(&vec_value) }, unsafe {
34+
MyVec::from_value(&vec_value).0
35+
});
36+
assert_eq!(
37+
unsafe { Vec::<String>::from_value(&my_vec_value) },
38+
unsafe { MyVec::from_value(&my_vec_value).0 }
39+
);
40+
41+
let opt = Some("foo".to_string());
42+
let opt_value = opt.to_value();
43+
let my_vec_manual_from_value = MyVecManualFrom::from(opt).to_value();
44+
45+
assert_eq!(
46+
MyVecManualFrom::static_type(),
47+
Option::<String>::static_type()
48+
);
49+
assert_eq!(
50+
opt_value.get::<Option<String>>().unwrap(),
51+
my_vec_manual_from_value.get::<Option<String>>().unwrap(),
52+
);
53+
assert_eq!(
54+
opt_value.value_type(),
55+
my_vec_manual_from_value.value_type()
56+
);
57+
assert_eq!(
58+
unsafe {
59+
Option::<String>::from_value(&opt_value)
60+
.into_iter()
61+
.collect::<Vec<_>>()
62+
},
63+
unsafe { MyVecManualFrom::from_value(&opt_value).0 }
64+
);
65+
assert_eq!(
66+
unsafe {
67+
Option::<String>::from_value(&my_vec_manual_from_value)
68+
.into_iter()
69+
.collect::<Vec<_>>()
70+
},
71+
unsafe { MyVecManualFrom::from_value(&my_vec_manual_from_value).0 }
72+
);
73+
}

0 commit comments

Comments
 (0)