Skip to content

Commit 0a85f76

Browse files
committed
ThreadGuard: Implement ToValue, Fromvalue and Default traits
This will also allow ThreadGuard to be used with the new property macro.
1 parent dcf23b2 commit 0a85f76

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

glib-macros/tests/properties.rs

+13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Take a look at the license at the top of the repository in the LICENSE file.
22

33
use glib::prelude::*;
4+
use glib::thread_guard::ThreadGuard;
45
use glib::ParamFlags;
56

67
#[cfg(test)]
@@ -87,6 +88,7 @@ mod foo {
8788
}
8889

8990
pub mod imp {
91+
use glib::thread_guard::ThreadGuard;
9092
use glib::{ParamSpec, Value};
9193
use std::rc::Rc;
9294

@@ -145,6 +147,8 @@ mod foo {
145147
cell: Cell<u8>,
146148
#[property(get = Self::overridden, override_class = Base)]
147149
overridden: PhantomData<u32>,
150+
#[property(name = "thread-guard", get, set)]
151+
thread_guard: RefCell<ThreadGuard<String>>,
148152
}
149153

150154
impl ObjectImpl for Foo {
@@ -195,6 +199,15 @@ fn props() {
195199
let bar: String = myfoo.property("bar");
196200
assert_eq!(bar, "".to_string());
197201

202+
// Set the thread guard
203+
myfoo.set_property("thread-guard", "foobar".to_value());
204+
// And grab directly the string from the guard after
205+
let bar: String = myfoo.property("thread-guard");
206+
assert_eq!(bar, "foobar".to_string());
207+
// Read it as a thread guard
208+
let bar = myfoo.property::<ThreadGuard<String>>("thread-guard");
209+
assert_eq!(bar.get_ref(), "foobar");
210+
198211
// Set bar
199212
myfoo.set_property("bar", "epic".to_value());
200213
let bar: String = myfoo.property("bar");

glib/src/property.rs

+11
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::sync::Arc;
99
use std::sync::Mutex;
1010
use std::sync::RwLock;
1111

12+
use crate::thread_guard::ThreadGuard;
1213
use crate::HasParamSpec;
1314

1415
// rustdoc-stripper-ignore-next
@@ -37,6 +38,9 @@ impl<T: Property> Property for Mutex<T> {
3738
impl<T: Property> Property for RwLock<T> {
3839
type Value = T::Value;
3940
}
41+
impl<T: Property> Property for ThreadGuard<T> {
42+
type Value = T::Value;
43+
}
4044
impl<T: Property> Property for once_cell::sync::OnceCell<T> {
4145
type Value = T::Value;
4246
}
@@ -131,6 +135,13 @@ impl<T> PropertySetNested for RwLock<T> {
131135
}
132136
}
133137

138+
impl<T> PropertyGet for ThreadGuard<T> {
139+
type Value = Self;
140+
fn get<R, F: Fn(&Self::Value) -> R>(&self, f: F) -> R {
141+
f(self)
142+
}
143+
}
144+
134145
impl<T> PropertyGet for once_cell::sync::OnceCell<T> {
135146
type Value = T;
136147
fn get<R, F: Fn(&Self::Value) -> R>(&self, f: F) -> R {

glib/src/thread_guard.rs

+42
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ use std::{
44
mem, ptr,
55
sync::atomic::{AtomicUsize, Ordering},
66
};
7+
8+
use crate::value::{FromValue, ValueTypeChecker, ValueTypeMismatchOrNoneError};
9+
use crate::{StaticType, ToValue, Type, Value};
10+
711
fn next_thread_id() -> usize {
812
static COUNTER: AtomicUsize = AtomicUsize::new(0);
913
COUNTER.fetch_add(1, Ordering::SeqCst)
@@ -111,4 +115,42 @@ impl<T> Drop for ThreadGuard<T> {
111115
}
112116
}
113117

118+
impl<T: Default> Default for ThreadGuard<T> {
119+
fn default() -> Self {
120+
Self::new(T::default())
121+
}
122+
}
123+
114124
unsafe impl<T> Send for ThreadGuard<T> {}
125+
126+
impl<T: ToValue + StaticType> ToValue for ThreadGuard<T> {
127+
fn to_value(&self) -> Value {
128+
T::to_value(self.get_ref())
129+
}
130+
131+
fn value_type(&self) -> Type {
132+
T::static_type()
133+
}
134+
}
135+
136+
impl<T: From<Value>> From<ThreadGuard<T>> for Value
137+
where
138+
Value: From<T>,
139+
{
140+
fn from(guard: ThreadGuard<T>) -> Self {
141+
Self::from(guard.into_inner())
142+
}
143+
}
144+
145+
unsafe impl<'a, T, C, E> FromValue<'a> for ThreadGuard<T>
146+
where
147+
T: FromValue<'a, Checker = C> + StaticType,
148+
C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
149+
E: std::error::Error + Send + Sized + 'static,
150+
{
151+
type Checker = T::Checker;
152+
153+
unsafe fn from_value(value: &'a Value) -> Self {
154+
Self::new(T::from_value(value))
155+
}
156+
}

0 commit comments

Comments
 (0)