Skip to content

Commit 31845c8

Browse files
authored
Merge pull request #1055 from SeaDve/into-value
glib-macros: generate "From<Ident> for Value" on ValueDelegate
2 parents b4f0881 + 62b1dfa commit 31845c8

File tree

3 files changed

+153
-4
lines changed

3 files changed

+153
-4
lines changed

glib-macros/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,14 @@ pub fn derive_props(input: TokenStream) -> TokenStream {
10131013
/// }
10141014
/// }
10151015
/// }
1016+
/// impl From<MyEnum> for u32 {
1017+
/// fn from(v: MyEnum) -> Self {
1018+
/// match v {
1019+
/// MyEnum::Zero => 0,
1020+
/// MyEnum::NotZero(x) => x
1021+
/// }
1022+
/// }
1023+
/// }
10161024
///
10171025
/// let myv = MyEnum::NotZero(34);
10181026
/// let convertedv = myv.to_value();

glib-macros/src/value_delegate_derive.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ pub fn impl_value_delegate(input: ValueDelegateInput) -> syn::Result<proc_macro:
158158
<#delegated_ty as #crate_ident::types::StaticType>::static_type()
159159
}
160160
}
161+
161162
impl #crate_ident::value::ToValue for #ident {
162163
fn to_value(&self) -> #crate_ident::value::Value {
163164
let this = self;
@@ -169,6 +170,12 @@ pub fn impl_value_delegate(input: ValueDelegateInput) -> syn::Result<proc_macro:
169170
}
170171
}
171172

173+
impl From<#ident> for #crate_ident::value::Value {
174+
fn from(this: #ident) -> Self {
175+
#crate_ident::value::Value::from(#delegate_value)
176+
}
177+
}
178+
172179
#to_value_optional
173180

174181
unsafe impl<'a> #crate_ident::value::FromValue<'a> for #ident {

glib-macros/tests/value_delegate_derive.rs

Lines changed: 138 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,144 @@
1-
use glib::{value::FromValue, HasParamSpec, StaticType, ToValue};
1+
use glib::{value::FromValue, StaticType, ToValue, Value, ValueDelegate};
2+
3+
#[test]
4+
fn into_value() {
5+
fn test_func(_: impl Into<Value>) {}
6+
7+
#[derive(ValueDelegate)]
8+
pub struct Test(i32);
9+
10+
#[derive(ValueDelegate)]
11+
#[value_delegate(nullable)]
12+
pub struct TestNullable(String);
13+
14+
#[derive(ValueDelegate)]
15+
#[value_delegate(from = i64)]
16+
pub struct TestManualFrom(i32);
17+
18+
impl From<i64> for TestManualFrom {
19+
fn from(v: i64) -> Self {
20+
Self(v as i32)
21+
}
22+
}
23+
impl<'a> From<&'a TestManualFrom> for i64 {
24+
fn from(v: &'a TestManualFrom) -> Self {
25+
v.0 as i64
26+
}
27+
}
28+
impl From<TestManualFrom> for i64 {
29+
fn from(v: TestManualFrom) -> Self {
30+
v.0 as i64
31+
}
32+
}
33+
34+
test_func(&Test(123));
35+
test_func(Test(123));
36+
37+
test_func(&TestManualFrom(123));
38+
test_func(TestManualFrom(123));
39+
40+
test_func(&TestNullable("foo".to_string()));
41+
test_func(TestNullable("foo".to_string()));
42+
test_func(Some(&TestNullable("foo".to_string())));
43+
test_func(&Some(TestNullable("foo".to_string())));
44+
test_func(Some(TestNullable("foo".to_string())));
45+
46+
assert_eq!(glib::Value::from(Test(123)).get::<Test>().unwrap().0, 123);
47+
assert_eq!(glib::Value::from(123).get::<Test>().unwrap().0, 123);
48+
assert_eq!(glib::Value::from(Test(123)).get::<i32>().unwrap(), 123);
49+
50+
assert_eq!(
51+
glib::Value::from(TestManualFrom(123))
52+
.get::<TestManualFrom>()
53+
.unwrap()
54+
.0,
55+
123
56+
);
57+
assert_eq!(
58+
glib::Value::from(123_i64)
59+
.get::<TestManualFrom>()
60+
.unwrap()
61+
.0,
62+
123
63+
);
64+
assert_eq!(
65+
glib::Value::from(TestManualFrom(123)).get::<i64>().unwrap(),
66+
123
67+
);
68+
69+
// From TestNullable
70+
assert_eq!(
71+
glib::Value::from(TestNullable("foo".to_string()))
72+
.get::<Option<TestNullable>>()
73+
.unwrap()
74+
.unwrap()
75+
.0,
76+
"foo"
77+
);
78+
assert_eq!(
79+
glib::Value::from("foo")
80+
.get::<Option<TestNullable>>()
81+
.unwrap()
82+
.unwrap()
83+
.0,
84+
"foo"
85+
);
86+
assert_eq!(
87+
glib::Value::from(TestNullable("foo".to_string()))
88+
.get::<Option<String>>()
89+
.unwrap()
90+
.unwrap(),
91+
"foo"
92+
);
93+
// From Option<TestNullable> Some
94+
assert_eq!(
95+
glib::Value::from(Some(TestNullable("foo".to_string())))
96+
.get::<Option<TestNullable>>()
97+
.unwrap()
98+
.unwrap()
99+
.0,
100+
"foo"
101+
);
102+
assert_eq!(
103+
glib::Value::from(Some("foo"))
104+
.get::<Option<TestNullable>>()
105+
.unwrap()
106+
.unwrap()
107+
.0,
108+
"foo"
109+
);
110+
assert_eq!(
111+
glib::Value::from(Some(TestNullable("foo".to_string())))
112+
.get::<Option<String>>()
113+
.unwrap()
114+
.unwrap(),
115+
"foo"
116+
);
117+
// From Option<TestNullable> None
118+
assert!(glib::Value::from(None::<TestNullable>)
119+
.get::<Option<TestNullable>>()
120+
.unwrap()
121+
.is_none());
122+
assert!(glib::Value::from(None::<String>)
123+
.get::<Option<TestNullable>>()
124+
.unwrap()
125+
.is_none());
126+
assert!(glib::Value::from(None::<TestNullable>)
127+
.get::<Option<String>>()
128+
.unwrap()
129+
.is_none());
130+
}
2131

3132
#[test]
4133
fn higher_level_types() {
5-
#[derive(Debug, glib::ValueDelegate)]
134+
#[derive(Debug, ValueDelegate)]
6135
pub struct MyVec(Vec<String>);
7136

8-
#[derive(Debug, glib::ValueDelegate)]
137+
#[derive(Debug, ValueDelegate)]
9138
#[value_delegate(nullable)]
10139
pub struct MyString(Box<str>);
11140

12-
#[derive(Debug, glib::ValueDelegate)]
141+
#[derive(Debug, ValueDelegate)]
13142
#[value_delegate(from = Option<String>)]
14143
struct MyVecManualFrom(Vec<String>);
15144

@@ -23,6 +152,11 @@ fn higher_level_types() {
23152
v.0.iter().next().cloned()
24153
}
25154
}
155+
impl From<MyVecManualFrom> for Option<String> {
156+
fn from(v: MyVecManualFrom) -> Self {
157+
v.0.into_iter().next()
158+
}
159+
}
26160

27161
let vec = vec!["foo".to_string(), "bar".to_string()];
28162
let vec_value = vec.to_value();

0 commit comments

Comments
 (0)