use super::error::Result;
pub trait Producer<T> {
fn send(&self, value: T) -> Result<()>;
fn try_send(&self, value: T) -> Result<()>;
fn is_full(&self) -> bool;
fn capacity(&self) -> Option<usize>;
}
pub trait Consumer<T> {
fn recv(&self) -> Result<T>;
fn try_recv(&self) -> Result<T>;
fn is_empty(&self) -> bool;
}
#[cfg(test)]
mod tests {
use super::{Consumer, Producer};
use crate::channel::{mpmc, spsc, MpmcChannel};
fn drain_into<P: Producer<u64>>(producer: &P, values: &[u64]) -> usize {
values
.iter()
.filter(|v| producer.try_send(**v).is_ok())
.count()
}
fn take_all<C: Consumer<u64>>(consumer: &C, limit: usize) -> Vec<u64> {
(0..limit)
.filter_map(|_| consumer.try_recv().ok())
.collect()
}
#[test]
fn spsc_halves_satisfy_the_roles() {
let (tx, rx) = spsc::<u64>(8);
assert_eq!(drain_into(&tx, &[1, 2, 3]), 3);
assert_eq!(take_all(&rx, 8), vec![1, 2, 3]);
}
#[test]
fn shareable_channels_and_their_halves_satisfy_the_roles() {
let channel = MpmcChannel::<u64>::new(Some(8));
assert_eq!(drain_into(&channel, &[7, 8]), 2);
assert_eq!(take_all(&channel, 8), vec![7, 8]);
let (tx, rx) = mpmc::<u64>(8);
assert_eq!(drain_into(&tx, &[9, 10]), 2);
assert_eq!(take_all(&rx, 8), vec![9, 10]);
}
#[test]
fn producer_reports_capacity_and_fullness() {
let (tx, rx) = spsc::<u64>(2);
assert_eq!(Producer::capacity(&tx), Some(2));
assert!(!Producer::is_full(&tx));
assert_eq!(drain_into(&tx, &[1, 2]), 2);
assert!(Producer::is_full(&tx));
assert!(!Consumer::is_empty(&rx));
}
}