Skip to content

Commit e5b2118

Browse files
committed
gio: add methods for returning and propagating boolean and int in/from a Task
When using Rust we prefer to use a `Value` for everything but gio also lets you return explicitly a `gboolean` or `gssize` which avoid boxing. Usage of these functions to return these kinds of values requires a call to the corresponding propagate function and you cannot mix them. Trying to extract a `Value` when either of them were used leads to an incorrect value. Expose methods in `Task` and `LocalTask` to return and propagate these kinds instead of assuming everything can go through a `Value`.
1 parent 9c05265 commit e5b2118

File tree

1 file changed

+98
-5
lines changed

1 file changed

+98
-5
lines changed

gio/src/task.rs

Lines changed: 98 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,6 @@ macro_rules! task_impl {
238238
}
239239

240240
#[doc(alias = "g_task_return_value")]
241-
#[doc(alias = "g_task_return_boolean")]
242-
#[doc(alias = "g_task_return_int")]
243241
#[doc(alias = "g_task_return_pointer")]
244242
#[doc(alias = "g_task_return_error")]
245243
#[allow(unused_unsafe)]
@@ -272,9 +270,26 @@ macro_rules! task_impl {
272270
}
273271
}
274272

273+
#[doc(alias = "g_task_return_boolean")]
274+
#[allow(unused_unsafe)]
275+
pub $($safety)? fn return_boolean_result(self, result: Result<bool, glib::Error>) {
276+
match result {
277+
Ok(v) => unsafe { ffi::g_task_return_boolean(self.to_glib_none().0, v as i32) },
278+
Err(e) => unsafe { ffi::g_task_return_error(self.to_glib_none().0, e.into_glib_ptr()) },
279+
}
280+
}
281+
282+
#[doc(alias = "g_task_return_int")]
283+
#[allow(unused_unsafe)]
284+
pub $($safety)? fn return_int_result(self, result: Result<isize, glib::Error>) {
285+
match result {
286+
Ok(v) => unsafe { ffi::g_task_return_int(self.to_glib_none().0, v) },
287+
Err(e) => unsafe { ffi::g_task_return_error(self.to_glib_none().0, e.into_glib_ptr()) },
288+
}
289+
}
290+
291+
275292
#[doc(alias = "g_task_propagate_value")]
276-
#[doc(alias = "g_task_propagate_boolean")]
277-
#[doc(alias = "g_task_propagate_int")]
278293
#[doc(alias = "g_task_propagate_pointer")]
279294
#[allow(unused_unsafe)]
280295
pub $($safety)? fn propagate(self) -> Result<V, glib::Error> {
@@ -313,6 +328,38 @@ macro_rules! task_impl {
313328
}
314329
}
315330
}
331+
332+
#[doc(alias = "g_task_propagate_boolean")]
333+
#[allow(unused_unsafe)]
334+
pub $($safety)? fn propagate_boolean(self) -> Result<bool, glib::Error> {
335+
let mut error = ptr::null_mut();
336+
337+
unsafe {
338+
let res = ffi::g_task_propagate_boolean(self.to_glib_none().0, &mut error);
339+
340+
if error.is_null() {
341+
Ok(res != 0)
342+
} else {
343+
Err(from_glib_full(error))
344+
}
345+
}
346+
}
347+
348+
#[doc(alias = "g_task_propagate_int")]
349+
#[allow(unused_unsafe)]
350+
pub $($safety)? fn propagate_int(self) -> Result<isize, glib::Error> {
351+
let mut error = ptr::null_mut();
352+
353+
unsafe {
354+
let res = ffi::g_task_propagate_int(self.to_glib_none().0, &mut error);
355+
356+
if error.is_null() {
357+
Ok(res)
358+
} else {
359+
Err(from_glib_full(error))
360+
}
361+
}
362+
}
316363
}
317364
}
318365
}
@@ -447,7 +494,7 @@ mod test {
447494
use crate::{prelude::*, test_util::run_async_local};
448495

449496
#[test]
450-
fn test_int_async_result() {
497+
fn test_int_value_async_result() {
451498
let fut = run_async_local(|tx, l| {
452499
let cancellable = crate::Cancellable::new();
453500
let task = unsafe {
@@ -469,6 +516,52 @@ mod test {
469516
}
470517
}
471518

519+
#[test]
520+
fn test_boolean_async_result() {
521+
let fut = run_async_local(|tx, l| {
522+
let cancellable = crate::Cancellable::new();
523+
let task = unsafe {
524+
crate::LocalTask::new(
525+
None,
526+
Some(&cancellable),
527+
move |t: LocalTask<bool>, _b: Option<&glib::Object>| {
528+
tx.send(t.propagate_boolean()).unwrap();
529+
l.quit();
530+
},
531+
)
532+
};
533+
task.return_boolean_result(Ok(true));
534+
});
535+
536+
match fut {
537+
Err(_) => panic!(),
538+
Ok(i) => assert!(i),
539+
}
540+
}
541+
542+
#[test]
543+
fn test_int_async_result() {
544+
let fut = run_async_local(|tx, l| {
545+
let cancellable = crate::Cancellable::new();
546+
let task = unsafe {
547+
crate::LocalTask::new(
548+
None,
549+
Some(&cancellable),
550+
move |t: LocalTask<i32>, _b: Option<&glib::Object>| {
551+
tx.send(t.propagate_int()).unwrap();
552+
l.quit();
553+
},
554+
)
555+
};
556+
task.return_int_result(Ok(100_isize));
557+
});
558+
559+
match fut {
560+
Err(_) => panic!(),
561+
Ok(i) => assert_eq!(i, 100),
562+
}
563+
}
564+
472565
#[test]
473566
fn test_object_async_result() {
474567
use glib::subclass::prelude::*;

0 commit comments

Comments
 (0)