bitwarden_ipc/traits/
communication_backend.rsuse crate::message::{IncomingMessage, OutgoingMessage};
pub trait CommunicationBackend {
type SendError;
type ReceiveError;
fn send(
&self,
message: OutgoingMessage,
) -> impl std::future::Future<Output = Result<(), Self::SendError>>;
fn receive(
&self,
) -> impl std::future::Future<Output = Result<IncomingMessage, Self::ReceiveError>>;
}
#[cfg(test)]
pub mod tests {
use std::{collections::VecDeque, rc::Rc};
use thiserror::Error;
use tokio::sync::RwLock;
use super::*;
#[derive(Debug, Clone)]
pub struct TestCommunicationBackend {
outgoing: Rc<RwLock<Vec<OutgoingMessage>>>,
incoming: Rc<RwLock<VecDeque<IncomingMessage>>>,
}
impl TestCommunicationBackend {
pub fn new() -> Self {
TestCommunicationBackend {
outgoing: Rc::new(RwLock::new(Vec::new())),
incoming: Rc::new(RwLock::new(VecDeque::new())),
}
}
pub async fn push_incoming(&self, message: IncomingMessage) {
self.incoming.write().await.push_back(message);
}
pub async fn outgoing(&self) -> Vec<OutgoingMessage> {
self.outgoing.read().await.clone()
}
}
#[derive(Debug, Clone, Error, PartialEq)]
pub enum TestCommunicationBackendReceiveError {
#[error("Could not receive mock message since no messages were queued")]
NoQueuedMessages,
}
impl CommunicationBackend for TestCommunicationBackend {
type SendError = ();
type ReceiveError = TestCommunicationBackendReceiveError;
async fn send(&self, message: OutgoingMessage) -> Result<(), Self::SendError> {
self.outgoing.write().await.push(message);
Ok(())
}
async fn receive(&self) -> Result<IncomingMessage, Self::ReceiveError> {
if let Some(message) = self.incoming.write().await.pop_front() {
Ok(message)
} else {
Err(TestCommunicationBackendReceiveError::NoQueuedMessages)
}
}
}
}