#[cfg(not(feature = "crossbeam"))]
use std::sync::mpsc::{channel as create_channel, Receiver, Sender};
#[cfg(not(feature = "crossbeam"))]
pub use std::sync::mpsc::RecvError;
#[cfg(not(feature = "crossbeam"))]
pub use std::sync::mpsc::SendError;
#[cfg(not(feature = "crossbeam"))]
pub use std::sync::mpsc::TryRecvError;
#[cfg(not(feature = "crossbeam"))]
pub use std::sync::mpsc::TrySendError;
#[cfg(feature = "crossbeam")]
use crossbeam_channel::{unbounded as create_channel, Receiver, Sender};
#[cfg(feature = "crossbeam")]
pub use crossbeam_channel::RecvError;
#[cfg(feature = "crossbeam")]
pub use crossbeam_channel::SendError;
#[cfg(feature = "crossbeam")]
pub use crossbeam_channel::TryRecvError;
#[cfg(feature = "crossbeam")]
pub use crossbeam_channel::TrySendError;
#[derive(Debug)]
pub struct Channel<S, R> {
sender: Sender<S>,
receiver: Receiver<R>,
}
#[cfg(feature = "crossbeam")]
impl<S, R> Clone for Channel<S, R> {
fn clone(&self) -> Self {
Channel {
sender: self.sender.clone(),
receiver: self.receiver.clone(),
}
}
}
impl<S, R> Channel<S, R> {
pub fn send(&self, s: S) -> Result<(), SendError<S>> {
self.sender.send(s)
}
pub fn recv(&self) -> Result<R, RecvError> {
self.receiver.recv()
}
pub fn try_recv(&self) -> Result<R, TryRecvError> {
self.receiver.try_recv()
}
}
pub fn channel<T, U>() -> (Channel<T, U>, Channel<U, T>) {
let (ls, lr) = create_channel();
let (rs, rr) = create_channel();
(
Channel {
sender: ls,
receiver: rr,
},
Channel {
sender: rs,
receiver: lr,
},
)
}
#[cfg(test)]
mod examples {
#[test]
fn test_threaded_scenario() {
let (thread, main) = crate::channel();
let handle = std::thread::spawn(move || loop {
match main.try_recv() {
Ok("stop") => break "stopped",
Err(crate::TryRecvError::Empty) => (),
_ => main.send("cant stop").unwrap(),
}
});
thread.send("slow down").unwrap();
assert_eq!(thread.recv().unwrap(), "cant stop");
thread.send("stop").unwrap();
assert_eq!(handle.join().unwrap(), "stopped");
}
}