gio/
dbus_method_invocation.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::{prelude::*, translate::*, VariantTy};
4
5use crate::{ffi, DBusMethodInvocation};
6
7impl DBusMethodInvocation {
8    #[doc(alias = "g_dbus_method_invocation_return_error_literal")]
9    pub fn return_error<T: ErrorDomain>(&self, error: T, message: &str) {
10        unsafe {
11            ffi::g_dbus_method_invocation_return_error_literal(
12                self.to_glib_full(),
13                T::domain().into_glib(),
14                error.code(),
15                message.to_glib_none().0,
16            );
17        }
18    }
19
20    #[doc(alias = "g_dbus_method_invocation_return_gerror")]
21    pub fn return_gerror(&self, error: glib::Error) {
22        unsafe {
23            ffi::g_dbus_method_invocation_return_gerror(
24                self.to_glib_full(),
25                error.to_glib_none().0,
26            );
27        }
28    }
29
30    // rustdoc-stripper-ignore-next
31    /// Return a result for this invocation.
32    ///
33    /// If `Ok` return the contained value with [`Self::return_value`].  If the return
34    /// value is not a tuple, automatically convert it to a one-element tuple, as
35    /// DBus return values must be tuples.
36    ///
37    /// If `Err` return the contained error with [`Self::return_gerror`].
38    pub fn return_result(self, result: Result<Option<glib::Variant>, glib::Error>) {
39        match result {
40            Ok(Some(value)) if !value.is_type(VariantTy::TUPLE) => {
41                let tupled = glib::Variant::tuple_from_iter(std::iter::once(value));
42                self.return_value(Some(&tupled));
43            }
44            Ok(value) => self.return_value(value.as_ref()),
45            Err(error) => self.return_gerror(error),
46        }
47    }
48
49    // rustdoc-stripper-ignore-next
50    /// Return an async result for this invocation.
51    ///
52    /// Spawn the given future on the thread-default main context, and return the
53    /// the result with [`Self::return_result`].  Specifically, if a variant is returned
54    /// that is not a tuple it is automatically wrapped into a tuple.
55    ///
56    /// The given `Future` does not have to be `Send`.
57    ///
58    /// This can be called only from the thread where the main context is running, e.g.
59    /// from any other `Future` that is executed on this main context, or after calling
60    /// `with_thread_default` or `acquire` on the main context.
61    pub fn return_future_local<F>(self, f: F) -> glib::JoinHandle<()>
62    where
63        F: std::future::Future<Output = Result<Option<glib::Variant>, glib::Error>> + 'static,
64    {
65        glib::spawn_future_local(async move {
66            self.return_result(f.await);
67        })
68    }
69}