use super::super::transport::{IpcError, IpcResult, IpcTransport};
use std::sync::Mutex;
use std::sync::mpsc;
pub struct LoopbackTransport {
tx: Mutex<mpsc::Sender<Vec<u8>>>,
rx: Mutex<mpsc::Receiver<Vec<u8>>>,
}
impl Default for LoopbackTransport {
fn default() -> Self {
Self::new()
}
}
impl LoopbackTransport {
pub fn new() -> Self {
let (tx, rx) = mpsc::channel();
Self { tx: Mutex::new(tx), rx: Mutex::new(rx) }
}
}
impl IpcTransport for LoopbackTransport {
fn kind(&self) -> &'static str {
"loopback"
}
fn publish(&self, bytes: &[u8]) -> IpcResult<()> {
self.tx
.lock()
.expect("loopback tx poisoned")
.send(bytes.to_vec())
.map_err(|_| IpcError::PeerGone)
}
fn try_recv(&self) -> IpcResult<Option<Vec<u8>>> {
match self.rx.lock().expect("loopback rx poisoned").try_recv() {
Ok(v) => Ok(Some(v)),
Err(mpsc::TryRecvError::Empty) => Ok(None),
Err(mpsc::TryRecvError::Disconnected) => Err(IpcError::PeerGone),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn publish_then_recv() {
let t = LoopbackTransport::new();
assert!(t.try_recv().unwrap().is_none());
t.publish(&[1, 2, 3]).unwrap();
assert_eq!(t.try_recv().unwrap(), Some(vec![1, 2, 3]));
assert!(t.try_recv().unwrap().is_none());
}
}