zbus/object_server/interface/
dispatch_result.rs

1use std::{future::Future, pin::Pin};
2
3use zbus::message::Flags;
4use zvariant::DynamicType;
5
6use crate::{message::Message, Connection, Result};
7use tracing::trace;
8
9/// A helper type returned by [`Interface`](`crate::object_server::Interface`) callbacks.
10pub enum DispatchResult<'a> {
11    /// This interface does not support the given method.
12    NotFound,
13
14    /// Retry with [Interface::call_mut](`crate::object_server::Interface::call_mut).
15    ///
16    /// This is equivalent to NotFound if returned by call_mut.
17    RequiresMut,
18
19    /// The method was found and will be completed by running this Future.
20    Async(Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>>),
21}
22
23impl<'a> DispatchResult<'a> {
24    /// Helper for creating the Async variant.
25    pub fn new_async<F, T, E>(conn: &'a Connection, msg: &'a Message, f: F) -> Self
26    where
27        F: Future<Output = ::std::result::Result<T, E>> + Send + 'a,
28        T: serde::Serialize + DynamicType + Send + Sync,
29        E: zbus::DBusError + Send,
30    {
31        DispatchResult::Async(Box::pin(async move {
32            let hdr = msg.header();
33            let ret = f.await;
34            if !hdr.primary().flags().contains(Flags::NoReplyExpected) {
35                match ret {
36                    Ok(r) => conn.reply(&hdr, &r).await,
37                    Err(e) => conn.reply_dbus_error(&hdr, e).await,
38                }
39                .map(|_seq| ())
40            } else {
41                trace!("No reply expected for {:?} by the caller.", msg);
42                Ok(())
43            }
44        }))
45    }
46}