zbus/object_server/interface/
interface_ref.rs

1use std::{marker::PhantomData, sync::Arc};
2
3use super::{Interface, InterfaceDeref, InterfaceDerefMut, SignalEmitter};
4use crate::async_lock::RwLock;
5
6/// Wrapper over an interface, along with its corresponding `SignalEmitter`
7/// instance. A reference to the underlying interface may be obtained via
8/// [`InterfaceRef::get`] and [`InterfaceRef::get_mut`].
9pub struct InterfaceRef<I> {
10    pub(crate) emitter: SignalEmitter<'static>,
11    pub(crate) lock: Arc<RwLock<dyn Interface>>,
12    pub(crate) phantom: PhantomData<I>,
13}
14
15impl<I> InterfaceRef<I>
16where
17    I: 'static,
18{
19    /// Get a reference to the underlying interface.
20    ///
21    /// **WARNING:** If methods (e.g property setters) in `ObjectServer` require `&mut self`
22    /// `ObjectServer` will not be able to access the interface in question until all references
23    /// of this method are dropped; it is highly recommended that the scope of the interface
24    /// returned is restricted.
25    pub async fn get(&self) -> InterfaceDeref<'_, I> {
26        let iface = self.lock.read().await;
27
28        iface
29            .downcast_ref::<I>()
30            .expect("Unexpected interface type");
31
32        InterfaceDeref {
33            iface,
34            phantom: PhantomData,
35        }
36    }
37
38    /// Get a reference to the underlying interface.
39    ///
40    /// **WARNINGS:** Since the `ObjectServer` will not be able to access the interface in question
41    /// until the return value of this method is dropped, it is highly recommended that the scope
42    /// of the interface returned is restricted.
43    ///
44    /// # Errors
45    ///
46    /// If the interface at this instance's path is not valid, an `Error::InterfaceNotFound` error
47    /// is returned.
48    ///
49    /// # Examples
50    ///
51    /// ```no_run
52    /// # use std::error::Error;
53    /// # use async_io::block_on;
54    /// # use zbus::{Connection, interface};
55    ///
56    /// struct MyIface(u32);
57    ///
58    /// #[interface(name = "org.myiface.MyIface")]
59    /// impl MyIface {
60    ///    #[zbus(property)]
61    ///    async fn count(&self) -> u32 {
62    ///        self.0
63    ///    }
64    /// }
65    ///
66    /// # block_on(async {
67    /// // Set up connection and object_server etc here and then in another part of the code:
68    /// # let connection = Connection::session().await?;
69    /// #
70    /// # let path = "/org/zbus/path";
71    /// # connection.object_server().at(path, MyIface(22)).await?;
72    /// let object_server = connection.object_server();
73    /// let iface_ref = object_server.interface::<_, MyIface>(path).await?;
74    /// let mut iface = iface_ref.get_mut().await;
75    /// iface.0 = 42;
76    /// iface.count_changed(iface_ref.signal_emitter()).await?;
77    /// # Ok::<_, Box<dyn Error + Send + Sync>>(())
78    /// # })?;
79    /// #
80    /// # Ok::<_, Box<dyn Error + Send + Sync>>(())
81    /// ```
82    pub async fn get_mut(&self) -> InterfaceDerefMut<'_, I> {
83        let mut iface = self.lock.write().await;
84
85        iface
86            .downcast_ref::<I>()
87            .expect("Unexpected interface type");
88        iface
89            .downcast_mut::<I>()
90            .expect("Unexpected interface type");
91
92        InterfaceDerefMut {
93            iface,
94            phantom: PhantomData,
95        }
96    }
97
98    pub fn signal_emitter(&self) -> &SignalEmitter<'static> {
99        &self.emitter
100    }
101
102    #[deprecated(since = "0.5.0", note = "Please use `signal_emitter` instead.")]
103    pub fn signal_context(&self) -> &SignalEmitter<'static> {
104        &self.emitter
105    }
106}
107
108impl<I> Clone for InterfaceRef<I> {
109    fn clone(&self) -> Self {
110        Self {
111            emitter: self.emitter.clone(),
112            lock: self.lock.clone(),
113            phantom: PhantomData,
114        }
115    }
116}