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}