Skip to content

Commit 627ef8a

Browse files
committed
Add ConstructCell with concrete Cell type, more tests
1 parent de40f9b commit 627ef8a

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

glib-macros/tests/properties.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ fn props() {
77
mod foo {
88
use glib::prelude::*;
99
use glib::subclass::prelude::*;
10-
use glib::ConstructRefCell;
10+
use glib::{ConstructCell, ConstructRefCell};
1111
use glib_macros::Properties;
1212
use std::cell::Cell;
1313
use std::cell::RefCell;
@@ -92,6 +92,8 @@ fn props() {
9292
#[property(get, set)]
9393
cell: Cell<u8>,
9494
#[property(get, set)]
95+
construct_cell: ConstructCell<u8>,
96+
#[property(get, set)]
9597
construct_ref_cell: ConstructRefCell<u8>,
9698
}
9799

@@ -111,6 +113,10 @@ fn props() {
111113
fn property(&self, _obj: &Self::Type, _id: usize, _pspec: &ParamSpec) -> Value {
112114
Self::derived_property(self, _obj, _id, _pspec).unwrap()
113115
}
116+
fn constructed(&self, _obj: &Self::Type) {
117+
self.construct_cell.replace(Some(1));
118+
self.construct_ref_cell.replace(Some(2));
119+
}
114120
}
115121

116122
#[glib::object_subclass]
@@ -227,6 +233,13 @@ fn props() {
227233
// member of struct field
228234
let author_nick = myfoo.author_nick();
229235
assert_eq!(author_nick, myfoo.property::<String>("author-nick"));
236+
237+
// construct_cell
238+
let n = myfoo.construct_cell();
239+
assert_eq!(n, myfoo.property::<u8>("construct-cell"));
240+
241+
let n = myfoo.construct_ref_cell();
242+
assert_eq!(n, myfoo.property::<u8>("construct-ref-cell"));
230243
}
231244

232245
// setters

glib/src/construct_cell.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{HasParamSpec, Property, PropertyGet, PropertySet, PropertySetNested}
44

55
use once_cell::sync::OnceCell as SyncOnceCell;
66
use once_cell::unsync::OnceCell;
7+
use std::cell::Cell;
78
use std::cell::RefCell;
89
use std::sync::Mutex;
910
use std::sync::RwLock;
@@ -100,3 +101,47 @@ define_construct!(@with_uninit_type ConstructSyncOnceCell, SyncOnceCell, T,
100101
oc
101102
}
102103
);
104+
105+
// Manual implementation because Cell often requires `Copy`, so `Debug` can't be derived,
106+
// `PropertyGet` and `PropertySet` can't be generated as with the other types...
107+
pub struct ConstructCell<T>(Cell<Option<T>>);
108+
impl<T> Default for ConstructCell<T> {
109+
fn default() -> Self {
110+
Self::new_empty()
111+
}
112+
}
113+
impl<T: Property + HasParamSpec> Property for ConstructCell<T> {
114+
type Value = T;
115+
}
116+
117+
impl<T> std::ops::Deref for ConstructCell<T> {
118+
type Target = Cell<Option<T>>;
119+
fn deref(&self) -> &Self::Target {
120+
&self.0
121+
}
122+
}
123+
impl<T> ConstructCell<T> {
124+
pub fn new(value: T) -> Self {
125+
Self(Cell::new(Some(value)))
126+
}
127+
pub fn new_empty() -> Self {
128+
Self(Cell::default())
129+
}
130+
}
131+
impl<T: Copy + std::fmt::Debug> std::fmt::Debug for ConstructCell<T> {
132+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133+
f.debug_struct("ConstructCell").field("0", &self.0).finish()
134+
}
135+
}
136+
impl<T: Copy> PropertySet for ConstructCell<T> {
137+
type SetValue = T;
138+
fn set(&self, v: T) {
139+
PropertySet::set(&self.0, Some(v))
140+
}
141+
}
142+
impl<T: Copy> PropertyGet for ConstructCell<T> {
143+
type Value = T;
144+
fn get<R, F: Fn(&Self::Value) -> R>(&self, f: F) -> R {
145+
PropertyGet::get(&self.0, |v| f(v.as_ref().unwrap()))
146+
}
147+
}

0 commit comments

Comments
 (0)