Skip to content

Commit 153d7e5

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 153d7e5

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

glib-macros/tests/properties.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ mod foo {
8888

8989
pub mod imp {
9090
use glib::{ParamSpec, Value};
91+
use glib::thread_guard::ThreadGuard;
9192
use std::rc::Rc;
9293

9394
use super::*;
@@ -145,6 +146,8 @@ mod foo {
145146
cell: Cell<u8>,
146147
#[property(get = Self::overridden, override_class = Base)]
147148
overridden: PhantomData<u32>,
149+
#[property(get, set, default = "")]
150+
thread_guard: RefCell<ThreadGuard<String>>,
148151
}
149152

150153
impl ObjectImpl for Foo {

glib/src/param_spec.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,6 +2065,17 @@ pub trait HasParamSpec {
20652065
fn param_spec_builder() -> Self::BuilderFn;
20662066
}
20672067

2068+
impl<T: HasParamSpec> HasParamSpec
2069+
for crate::thread_guard::ThreadGuard<T>
2070+
{
2071+
type ParamSpec = T::ParamSpec;
2072+
type SetValue = T::SetValue;
2073+
type BuilderFn = T::BuilderFn;
2074+
2075+
fn param_spec_builder() -> Self::BuilderFn {
2076+
T::param_spec_builder()
2077+
}
2078+
}
20682079
impl<T: crate::value::ToValueOptional + HasParamSpec> HasParamSpec for Option<T> {
20692080
type ParamSpec = T::ParamSpec;
20702081
type SetValue = T::SetValue;

glib/src/thread_guard.rs

Lines changed: 40 additions & 0 deletions
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,40 @@ 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+
unsafe impl<'a, T, C, E> FromValue<'a> for ThreadGuard<T>
137+
where
138+
T: FromValue<'a, Checker = C> + StaticType,
139+
C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError<E>>,
140+
E: std::error::Error + Send + Sized + 'static,
141+
{
142+
type Checker = T::Checker;
143+
144+
unsafe fn from_value(value: &'a Value) -> Self {
145+
match T::Checker::check(value) {
146+
Err(ValueTypeMismatchOrNoneError::UnexpectedNone) => panic!(),
147+
Err(ValueTypeMismatchOrNoneError::WrongValueType(_err)) => {
148+
// This should've been caught by the caller already.
149+
unreachable!();
150+
}
151+
Ok(_) => Self::new(T::from_value(value)),
152+
}
153+
}
154+
}

0 commit comments

Comments
 (0)