bitwarden_ipc/traits/
communication_backend.rs1use std::fmt::Debug;
2
3use crate::{
4 error::IpcErrorKind,
5 message::{IncomingMessage, OutgoingMessage},
6};
7
8pub trait CommunicationBackend: Send + Sync + 'static {
12 type SendError: Debug + Send + Sync + 'static + IpcErrorKind;
14 type Receiver: CommunicationBackendReceiver;
16
17 fn send(
28 &self,
29 message: OutgoingMessage,
30 ) -> impl std::future::Future<Output = Result<(), Self::SendError>> + Send + Sync;
31
32 fn subscribe(&self) -> impl std::future::Future<Output = Self::Receiver> + Send + Sync;
40}
41
42pub trait CommunicationBackendReceiver: Send + Sync + 'static {
49 type ReceiveError: Debug + Send + Sync + 'static + IpcErrorKind;
51
52 fn receive(
62 &self,
63 ) -> impl std::future::Future<Output = Result<IncomingMessage, Self::ReceiveError>> + Send + Sync;
64}
65
66pub(crate) mod noop {
67 use super::*;
68
69 pub struct NoopCommunicationBackend;
74
75 pub struct NoopCommunicationBackendReceiver;
77
78 impl CommunicationBackend for NoopCommunicationBackend {
79 type SendError = std::convert::Infallible;
80 type Receiver = NoopCommunicationBackendReceiver;
81
82 async fn send(&self, _message: OutgoingMessage) -> Result<(), Self::SendError> {
83 Ok(())
84 }
85
86 async fn subscribe(&self) -> Self::Receiver {
87 NoopCommunicationBackendReceiver
88 }
89 }
90
91 impl CommunicationBackendReceiver for NoopCommunicationBackendReceiver {
92 type ReceiveError = std::convert::Infallible;
93
94 async fn receive(&self) -> Result<IncomingMessage, Self::ReceiveError> {
95 std::future::pending().await
96 }
97 }
98}
99
100#[cfg(any(test, feature = "test-support"))]
101pub(crate) mod test_support {
102 use std::sync::Arc;
103
104 use tokio::sync::{
105 Mutex, RwLock,
106 broadcast::{self, Receiver, Sender},
107 };
108
109 use super::*;
110
111 #[derive(Debug)]
114 pub struct TestCommunicationBackend {
115 outgoing_tx: Sender<OutgoingMessage>,
116 outgoing_rx: Receiver<OutgoingMessage>,
117 outgoing: Arc<RwLock<Vec<OutgoingMessage>>>,
118 incoming_tx: Sender<IncomingMessage>,
119 incoming_rx: Receiver<IncomingMessage>,
120 }
121
122 impl Clone for TestCommunicationBackend {
123 fn clone(&self) -> Self {
124 TestCommunicationBackend {
125 outgoing_tx: self.outgoing_tx.clone(),
126 outgoing_rx: self.outgoing_rx.resubscribe(),
127 outgoing: self.outgoing.clone(),
128 incoming_tx: self.incoming_tx.clone(),
129 incoming_rx: self.incoming_rx.resubscribe(),
130 }
131 }
132 }
133
134 impl Default for TestCommunicationBackend {
135 fn default() -> Self {
136 Self::new()
137 }
138 }
139
140 #[derive(Debug)]
142 pub struct TestCommunicationBackendReceiver(RwLock<Receiver<IncomingMessage>>);
143
144 impl TestCommunicationBackend {
145 pub fn new() -> Self {
147 let (outgoing_tx, outgoing_rx) = broadcast::channel(10);
148 let (incoming_tx, incoming_rx) = broadcast::channel(10);
149 TestCommunicationBackend {
150 outgoing_tx,
151 outgoing_rx,
152 outgoing: Arc::new(RwLock::new(Vec::new())),
153 incoming_tx,
154 incoming_rx,
155 }
156 }
157
158 pub fn push_incoming(&self, message: IncomingMessage) {
160 self.incoming_tx
161 .send(message)
162 .expect("Failed to send incoming message");
163 }
164
165 pub async fn outgoing(&self) -> Vec<OutgoingMessage> {
167 self.outgoing.read().await.clone()
168 }
169
170 pub async fn drain_outgoing(&self) -> Vec<OutgoingMessage> {
172 self.outgoing.write().await.drain(..).collect()
173 }
174 }
175
176 impl CommunicationBackend for TestCommunicationBackend {
177 type SendError = ();
178 type Receiver = TestCommunicationBackendReceiver;
179
180 async fn send(&self, message: OutgoingMessage) -> Result<(), Self::SendError> {
181 self.outgoing.write().await.push(message);
182 Ok(())
183 }
184
185 async fn subscribe(&self) -> Self::Receiver {
186 TestCommunicationBackendReceiver(RwLock::new(self.incoming_rx.resubscribe()))
187 }
188 }
189
190 impl CommunicationBackendReceiver for TestCommunicationBackendReceiver {
191 type ReceiveError = ();
192
193 async fn receive(&self) -> Result<IncomingMessage, Self::ReceiveError> {
194 Ok(self
195 .0
196 .write()
197 .await
198 .recv()
199 .await
200 .expect("Failed to receive incoming message"))
201 }
202 }
203
204 #[allow(unused)]
205 #[derive(Clone)]
206 pub struct TestTwoWayCommunicationBackend {
207 outgoing: broadcast::Sender<OutgoingMessage>,
208 receiver: TestTwoWayCommunicationBackendReceiver,
209 }
210
211 #[allow(unused)]
212 #[derive(Clone)]
213 pub struct TestTwoWayCommunicationBackendReceiver {
214 incoming: Arc<Mutex<broadcast::Receiver<OutgoingMessage>>>,
215 }
216
217 impl CommunicationBackendReceiver for TestTwoWayCommunicationBackendReceiver {
218 type ReceiveError = ();
219
220 async fn receive(&self) -> Result<IncomingMessage, Self::ReceiveError> {
221 let mut incoming = self.incoming.lock().await;
222 let message = incoming
223 .recv()
224 .await
225 .expect("Failed to receive incoming message");
226 Ok(IncomingMessage {
227 payload: message.payload,
228 destination: message.destination,
229 source: crate::endpoint::Source::DesktopMain,
230 topic: message.topic,
231 })
232 }
233 }
234
235 impl TestTwoWayCommunicationBackend {
236 #[allow(unused)]
237 pub fn new() -> (Self, Self) {
238 let (outgoing0, incoming0) = broadcast::channel(128);
239 let (outgoing1, incoming1) = broadcast::channel(128);
240 let one = TestTwoWayCommunicationBackend {
241 outgoing: outgoing0,
242 receiver: TestTwoWayCommunicationBackendReceiver {
243 incoming: Arc::new(Mutex::new(incoming1)),
244 },
245 };
246 let two = TestTwoWayCommunicationBackend {
247 outgoing: outgoing1,
248 receiver: TestTwoWayCommunicationBackendReceiver {
249 incoming: Arc::new(Mutex::new(incoming0)),
250 },
251 };
252 (one, two)
253 }
254 }
255
256 impl CommunicationBackend for TestTwoWayCommunicationBackend {
257 type SendError = ();
258 type Receiver = TestTwoWayCommunicationBackendReceiver;
259
260 async fn send(&self, message: OutgoingMessage) -> Result<(), Self::SendError> {
261 self.outgoing
262 .send(message)
263 .expect("Failed to send outgoing message");
264 Ok(())
265 }
266
267 async fn subscribe(&self) -> Self::Receiver {
268 TestTwoWayCommunicationBackendReceiver {
269 incoming: Arc::new(Mutex::new(
270 self.receiver.incoming.lock().await.resubscribe(),
271 )),
272 }
273 }
274 }
275}