bitwarden_ipc/traits/
communication_backend.rs1use std::fmt::Debug;
2
3use crate::message::{IncomingMessage, OutgoingMessage};
4
5pub trait CommunicationBackend: Send + Sync + 'static {
9 type SendError: Debug + Send + Sync + 'static;
10 type Receiver: CommunicationBackendReceiver;
11
12 fn send(
21 &self,
22 message: OutgoingMessage,
23 ) -> impl std::future::Future<Output = Result<(), Self::SendError>> + Send;
24
25 fn subscribe(&self) -> impl std::future::Future<Output = Self::Receiver> + Send + Sync;
33}
34
35pub trait CommunicationBackendReceiver: Send + Sync + 'static {
42 type ReceiveError: Debug + Send + Sync + 'static;
43
44 fn receive(
52 &self,
53 ) -> impl std::future::Future<Output = Result<IncomingMessage, Self::ReceiveError>> + Send + Sync;
54}
55
56#[cfg(test)]
57pub mod tests {
58 use std::sync::Arc;
59
60 use tokio::sync::{
61 broadcast::{self, Receiver, Sender},
62 RwLock,
63 };
64
65 use super::*;
66
67 #[derive(Debug)]
69 pub struct TestCommunicationBackend {
70 outgoing_tx: Sender<OutgoingMessage>,
71 outgoing_rx: Receiver<OutgoingMessage>,
72 outgoing: Arc<RwLock<Vec<OutgoingMessage>>>,
73 incoming_tx: Sender<IncomingMessage>,
74 incoming_rx: Receiver<IncomingMessage>,
75 }
76
77 impl Clone for TestCommunicationBackend {
78 fn clone(&self) -> Self {
79 TestCommunicationBackend {
80 outgoing_tx: self.outgoing_tx.clone(),
81 outgoing_rx: self.outgoing_rx.resubscribe(),
82 outgoing: self.outgoing.clone(),
83 incoming_tx: self.incoming_tx.clone(),
84 incoming_rx: self.incoming_rx.resubscribe(),
85 }
86 }
87 }
88
89 #[derive(Debug)]
90 pub struct TestCommunicationBackendReceiver(RwLock<Receiver<IncomingMessage>>);
91
92 impl TestCommunicationBackend {
93 pub fn new() -> Self {
94 let (outgoing_tx, outgoing_rx) = broadcast::channel(10);
95 let (incoming_tx, incoming_rx) = broadcast::channel(10);
96 TestCommunicationBackend {
97 outgoing_tx,
98 outgoing_rx,
99 outgoing: Arc::new(RwLock::new(Vec::new())),
100 incoming_tx,
101 incoming_rx,
102 }
103 }
104
105 pub fn push_incoming(&self, message: IncomingMessage) {
106 self.incoming_tx
107 .send(message)
108 .expect("Failed to send incoming message");
109 }
110
111 pub async fn outgoing(&self) -> Vec<OutgoingMessage> {
113 self.outgoing.read().await.clone()
114 }
115 }
116
117 impl CommunicationBackend for TestCommunicationBackend {
118 type SendError = ();
119 type Receiver = TestCommunicationBackendReceiver;
120
121 async fn send(&self, message: OutgoingMessage) -> Result<(), Self::SendError> {
122 self.outgoing.write().await.push(message);
123 Ok(())
124 }
125
126 async fn subscribe(&self) -> Self::Receiver {
127 TestCommunicationBackendReceiver(RwLock::new(self.incoming_rx.resubscribe()))
128 }
129 }
130
131 impl CommunicationBackendReceiver for TestCommunicationBackendReceiver {
132 type ReceiveError = ();
133
134 async fn receive(&self) -> Result<IncomingMessage, Self::ReceiveError> {
135 Ok(self
136 .0
137 .write()
138 .await
139 .recv()
140 .await
141 .expect("Failed to receive incoming message"))
142 }
143 }
144}