bitwarden_ipc/traits/
communication_backend.rs1use std::fmt::Debug;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 broadcast::BroadcastGroup,
7 endpoint::Endpoint,
8 error::IpcErrorKind,
9 message::{IncomingMessage, OutgoingMessage},
10};
11
12#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
15#[bitwarden_ffi::wasm_record]
16pub enum BroadcastResolution {
17 Endpoints(Vec<Endpoint>),
20 Delegate(Endpoint),
25 Unsupported,
28}
29
30pub trait CommunicationBackend: Send + Sync + 'static {
34 type SendError: Debug + Send + Sync + 'static + IpcErrorKind;
36 type Receiver: CommunicationBackendReceiver;
38
39 fn send(
50 &self,
51 message: OutgoingMessage,
52 ) -> impl std::future::Future<Output = Result<(), Self::SendError>> + Send + Sync;
53
54 fn resolve(
62 &self,
63 _group: &BroadcastGroup,
64 ) -> impl std::future::Future<Output = BroadcastResolution> + Send + Sync {
65 async { BroadcastResolution::Unsupported }
66 }
67
68 fn subscribe(&self) -> impl std::future::Future<Output = Self::Receiver> + Send + Sync;
76}
77
78pub trait CommunicationBackendReceiver: Send + Sync + 'static {
85 type ReceiveError: Debug + Send + Sync + 'static + IpcErrorKind;
87
88 fn receive(
98 &self,
99 ) -> impl std::future::Future<Output = Result<IncomingMessage, Self::ReceiveError>> + Send + Sync;
100}
101
102pub(crate) mod noop {
103 use super::*;
104
105 pub struct NoopCommunicationBackend;
110
111 pub struct NoopCommunicationBackendReceiver;
113
114 impl CommunicationBackend for NoopCommunicationBackend {
115 type SendError = std::convert::Infallible;
116 type Receiver = NoopCommunicationBackendReceiver;
117
118 async fn send(&self, _message: OutgoingMessage) -> Result<(), Self::SendError> {
119 Ok(())
120 }
121
122 async fn subscribe(&self) -> Self::Receiver {
123 NoopCommunicationBackendReceiver
124 }
125 }
126
127 impl CommunicationBackendReceiver for NoopCommunicationBackendReceiver {
128 type ReceiveError = std::convert::Infallible;
129
130 async fn receive(&self) -> Result<IncomingMessage, Self::ReceiveError> {
131 std::future::pending().await
132 }
133 }
134}
135
136#[cfg(any(test, feature = "test-support"))]
137pub(crate) mod test_support {
138 use std::sync::Arc;
139
140 use tokio::sync::{
141 Mutex, RwLock,
142 broadcast::{self, Receiver, Sender},
143 };
144
145 use super::*;
146
147 #[derive(Debug)]
150 pub struct TestCommunicationBackend {
151 outgoing_tx: Sender<OutgoingMessage>,
152 outgoing_rx: Receiver<OutgoingMessage>,
153 outgoing: Arc<RwLock<Vec<OutgoingMessage>>>,
154 incoming_tx: Sender<IncomingMessage>,
155 incoming_rx: Receiver<IncomingMessage>,
156 resolution: Arc<RwLock<Option<BroadcastResolution>>>,
157 }
158
159 impl Clone for TestCommunicationBackend {
160 fn clone(&self) -> Self {
161 TestCommunicationBackend {
162 outgoing_tx: self.outgoing_tx.clone(),
163 outgoing_rx: self.outgoing_rx.resubscribe(),
164 outgoing: self.outgoing.clone(),
165 incoming_tx: self.incoming_tx.clone(),
166 incoming_rx: self.incoming_rx.resubscribe(),
167 resolution: self.resolution.clone(),
168 }
169 }
170 }
171
172 impl Default for TestCommunicationBackend {
173 fn default() -> Self {
174 Self::new()
175 }
176 }
177
178 #[derive(Debug)]
180 pub struct TestCommunicationBackendReceiver(RwLock<Receiver<IncomingMessage>>);
181
182 impl TestCommunicationBackend {
183 pub fn new() -> Self {
185 let (outgoing_tx, outgoing_rx) = broadcast::channel(10);
186 let (incoming_tx, incoming_rx) = broadcast::channel(10);
187 TestCommunicationBackend {
188 outgoing_tx,
189 outgoing_rx,
190 outgoing: Arc::new(RwLock::new(Vec::new())),
191 incoming_tx,
192 incoming_rx,
193 resolution: Arc::new(RwLock::new(None)),
194 }
195 }
196
197 pub async fn set_resolution(&self, resolution: BroadcastResolution) {
201 *self.resolution.write().await = Some(resolution);
202 }
203
204 pub fn push_incoming(&self, message: IncomingMessage) {
206 self.incoming_tx
207 .send(message)
208 .expect("Failed to send incoming message");
209 }
210
211 pub async fn outgoing(&self) -> Vec<OutgoingMessage> {
213 self.outgoing.read().await.clone()
214 }
215
216 pub async fn drain_outgoing(&self) -> Vec<OutgoingMessage> {
218 self.outgoing.write().await.drain(..).collect()
219 }
220 }
221
222 impl CommunicationBackend for TestCommunicationBackend {
223 type SendError = ();
224 type Receiver = TestCommunicationBackendReceiver;
225
226 async fn send(&self, message: OutgoingMessage) -> Result<(), Self::SendError> {
227 self.outgoing.write().await.push(message);
228 Ok(())
229 }
230
231 async fn resolve(&self, _group: &BroadcastGroup) -> BroadcastResolution {
232 self.resolution
233 .read()
234 .await
235 .clone()
236 .unwrap_or(BroadcastResolution::Unsupported)
237 }
238
239 async fn subscribe(&self) -> Self::Receiver {
240 TestCommunicationBackendReceiver(RwLock::new(self.incoming_rx.resubscribe()))
241 }
242 }
243
244 impl CommunicationBackendReceiver for TestCommunicationBackendReceiver {
245 type ReceiveError = ();
246
247 async fn receive(&self) -> Result<IncomingMessage, Self::ReceiveError> {
248 Ok(self
249 .0
250 .write()
251 .await
252 .recv()
253 .await
254 .expect("Failed to receive incoming message"))
255 }
256 }
257
258 #[allow(unused)]
259 #[derive(Clone)]
260 pub struct TestTwoWayCommunicationBackend {
261 outgoing: broadcast::Sender<OutgoingMessage>,
262 receiver: TestTwoWayCommunicationBackendReceiver,
263 }
264
265 #[allow(unused)]
266 #[derive(Clone)]
267 pub struct TestTwoWayCommunicationBackendReceiver {
268 incoming: Arc<Mutex<broadcast::Receiver<OutgoingMessage>>>,
269 }
270
271 impl CommunicationBackendReceiver for TestTwoWayCommunicationBackendReceiver {
272 type ReceiveError = ();
273
274 async fn receive(&self) -> Result<IncomingMessage, Self::ReceiveError> {
275 let mut incoming = self.incoming.lock().await;
276 let message = incoming
277 .recv()
278 .await
279 .expect("Failed to receive incoming message");
280 Ok(IncomingMessage {
281 payload: message.payload,
282 destination: message.destination,
283 source: crate::endpoint::Source::DesktopMain,
284 topic: message.topic,
285 })
286 }
287 }
288
289 impl TestTwoWayCommunicationBackend {
290 #[allow(unused)]
291 pub fn new() -> (Self, Self) {
292 let (outgoing0, incoming0) = broadcast::channel(128);
293 let (outgoing1, incoming1) = broadcast::channel(128);
294 let one = TestTwoWayCommunicationBackend {
295 outgoing: outgoing0,
296 receiver: TestTwoWayCommunicationBackendReceiver {
297 incoming: Arc::new(Mutex::new(incoming1)),
298 },
299 };
300 let two = TestTwoWayCommunicationBackend {
301 outgoing: outgoing1,
302 receiver: TestTwoWayCommunicationBackendReceiver {
303 incoming: Arc::new(Mutex::new(incoming0)),
304 },
305 };
306 (one, two)
307 }
308 }
309
310 impl CommunicationBackend for TestTwoWayCommunicationBackend {
311 type SendError = ();
312 type Receiver = TestTwoWayCommunicationBackendReceiver;
313
314 async fn send(&self, message: OutgoingMessage) -> Result<(), Self::SendError> {
315 self.outgoing
316 .send(message)
317 .expect("Failed to send outgoing message");
318 Ok(())
319 }
320
321 async fn subscribe(&self) -> Self::Receiver {
322 TestTwoWayCommunicationBackendReceiver {
323 incoming: Arc::new(Mutex::new(
324 self.receiver.incoming.lock().await.resubscribe(),
325 )),
326 }
327 }
328 }
329}