Skip to content

Commit babbc2a

Browse files
felinirabilelmoussaoui
authored andcommitted
glib-macros: Allow to omit set for construct_only properties
1 parent 39adfe0 commit babbc2a

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

glib-macros/src/properties.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ struct PropDesc {
236236
member: Option<syn::Ident>,
237237
builder: Option<(Punctuated<syn::Expr, Token![,]>, TokenStream2)>,
238238
builder_fields: HashMap<syn::Ident, Option<syn::Expr>>,
239+
is_construct_only: bool,
239240
}
240241

241242
impl PropDesc {
@@ -248,7 +249,7 @@ impl PropDesc {
248249
let ReceivedAttrs {
249250
nullable,
250251
get,
251-
set,
252+
mut set,
252253
override_class,
253254
override_interface,
254255
ty,
@@ -258,6 +259,17 @@ impl PropDesc {
258259
builder_fields,
259260
} = attrs;
260261

262+
let is_construct_only = if builder_fields.iter().any(|(k, _)| *k == "construct_only") {
263+
// Insert a default setter automatically
264+
if set.is_none() {
265+
set = Some(MaybeCustomFn::Default);
266+
}
267+
268+
true
269+
} else {
270+
false
271+
};
272+
261273
if get.is_none() && set.is_none() {
262274
return Err(syn::Error::new(
263275
attrs_span,
@@ -295,6 +307,7 @@ impl PropDesc {
295307
member,
296308
builder,
297309
builder_fields,
310+
is_construct_only,
298311
})
299312
}
300313
}
@@ -534,8 +547,8 @@ fn expand_wrapper_getset_properties(props: &[PropDesc]) -> TokenStream2 {
534547
self.property::<<#ty as #crate_ident::Property>::Value>(#stripped_name)
535548
})
536549
});
537-
let is_construct_only = p.builder_fields.iter().any(|(k, _)| *k == "construct_only");
538-
let setter = (p.set.is_some() && !is_construct_only).then(|| {
550+
551+
let setter = (p.set.is_some() && !p.is_construct_only).then(|| {
539552
let ident = format_ident!("set_{}", ident);
540553
let target_ty = quote!(<<#ty as #crate_ident::Property>::Value as #crate_ident::HasParamSpec>::SetValue);
541554
let set_ty = if p.nullable {

glib-macros/tests/properties.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ mod foo {
160160
weak_ref_prop: glib::WeakRef<glib::Object>,
161161
#[property(get, set)]
162162
send_weak_ref_prop: glib::SendWeakRef<glib::Object>,
163+
#[property(get, default_value = 0, construct_only)]
164+
construct_only_cell: OnceCell<u32>,
165+
#[property(get, set = Self::set_construct_only_custom, construct_only)]
166+
construct_only_custom_setter: OnceCell<Option<String>>,
163167
}
164168

165169
impl ObjectImpl for Foo {
@@ -194,6 +198,11 @@ mod foo {
194198
fn overridden(&self) -> u32 {
195199
43
196200
}
201+
fn set_construct_only_custom(&self, value: Option<String>) {
202+
self.construct_only_custom_setter
203+
.set(value.map(|v| format!("custom set: {}", v)))
204+
.expect("Setter to be only called once");
205+
}
197206
}
198207
}
199208

@@ -382,7 +391,22 @@ fn props() {
382391
// object subclass
383392
let myobj = glib::BoxedAnyObject::new("");
384393
myfoo.set_object(Some(myobj.upcast_ref()));
385-
assert_eq!(myfoo.object(), Some(myobj.upcast()))
394+
assert_eq!(myfoo.object(), Some(myobj.upcast()));
395+
396+
// construct_only
397+
let myfoo: foo::Foo = glib::object::Object::builder()
398+
.property("construct-only-cell", 1u32)
399+
.build();
400+
assert_eq!(myfoo.construct_only_cell(), 1u32);
401+
402+
// construct_only with custom setter
403+
let myfoo: foo::Foo = glib::object::Object::builder()
404+
.property("construct-only-custom-setter", "foo")
405+
.build();
406+
assert_eq!(
407+
myfoo.construct_only_custom_setter(),
408+
Some("custom set: foo".to_owned())
409+
);
386410
}
387411

388412
#[cfg(test)]

0 commit comments

Comments
 (0)