zbus/object_server/
signal_emitter.rs

1use zbus_names::{BusName, InterfaceName, MemberName};
2
3use crate::{zvariant::ObjectPath, Connection, Error, Result};
4
5/// A signal emitter.
6///
7/// For signal emission using the high-level API, you'll need instances of this type.
8///
9/// See [`crate::object_server::InterfaceRef::signal_emitter`] and [`crate::interface`]
10/// documentation for details and examples of this type in use.
11#[derive(Clone, Debug)]
12pub struct SignalEmitter<'s> {
13    conn: Connection,
14    path: ObjectPath<'s>,
15    destination: Option<BusName<'s>>,
16}
17
18impl<'s> SignalEmitter<'s> {
19    /// Create a new signal context for the given connection and object path.
20    pub fn new<P>(conn: &Connection, path: P) -> Result<Self>
21    where
22        P: TryInto<ObjectPath<'s>>,
23        P::Error: Into<Error>,
24    {
25        path.try_into()
26            .map(|p| Self {
27                conn: conn.clone(),
28                path: p,
29                destination: None,
30            })
31            .map_err(Into::into)
32    }
33
34    /// Create a new signal context for the given connection and object path.
35    pub fn from_parts(conn: Connection, path: ObjectPath<'s>) -> Self {
36        Self {
37            conn,
38            path,
39            destination: None,
40        }
41    }
42
43    /// Emit a signal on the given interface with the given signal name and body.
44    pub async fn emit<'i, 'm, I, M, B>(&self, interface: I, signal_name: M, body: &B) -> Result<()>
45    where
46        I: TryInto<InterfaceName<'i>>,
47        I::Error: Into<Error>,
48        M: TryInto<MemberName<'m>>,
49        M::Error: Into<Error>,
50        B: serde::ser::Serialize + zvariant::DynamicType,
51    {
52        self.conn
53            .emit_signal(
54                self.destination.as_ref(),
55                &self.path,
56                interface,
57                signal_name,
58                body,
59            )
60            .await
61    }
62
63    /// Set the destination for the signal emission.
64    ///
65    /// Signals are typically broadcasted and thus don't have a destination. However, there are
66    /// cases where you need to unicast signals to specific peers. This method allows you to set the
67    /// destination for the signals emitted with this context.
68    pub fn set_destination(mut self, destination: BusName<'s>) -> Self {
69        self.destination = Some(destination);
70
71        self
72    }
73
74    /// Get a reference to the associated connection.
75    pub fn connection(&self) -> &Connection {
76        &self.conn
77    }
78
79    /// Get a reference to the associated object path.
80    pub fn path(&self) -> &ObjectPath<'s> {
81        &self.path
82    }
83
84    /// Get a reference to the associated destination (if any).
85    pub fn destination(&self) -> Option<&BusName<'s>> {
86        self.destination.as_ref()
87    }
88
89    /// Create an owned clone of `self`.
90    pub fn to_owned(&self) -> SignalEmitter<'static> {
91        SignalEmitter {
92            conn: self.conn.clone(),
93            path: self.path.to_owned(),
94            destination: self.destination.as_ref().map(|d| d.to_owned()),
95        }
96    }
97
98    /// Convert into an owned clone of `self`.
99    pub fn into_owned(self) -> SignalEmitter<'static> {
100        SignalEmitter {
101            conn: self.conn,
102            path: self.path.into_owned(),
103            destination: self.destination.map(|d| d.into_owned()),
104        }
105    }
106}