use core::fmt;
use std::rc::Rc;
use super::chan::{Chan, Limit};
use crate::sync::mpsc::error::SendError;
pub(super) struct Unbounded;
impl Limit for Unbounded {
fn release(&self, _n: usize) {}
fn is_idle(&self) -> bool {
true
}
fn close(&self) {}
}
pub fn unbounded_channel<T>() -> (UnboundedSender<T>, UnboundedReceiver<T>) {
let chan = Rc::new(Chan::new(Unbounded));
let tx = UnboundedSender {
chan: Rc::clone(&chan),
};
(tx, UnboundedReceiver { chan })
}
pub struct UnboundedSender<T> {
chan: Rc<Chan<T, Unbounded>>,
}
impl<T> UnboundedSender<T> {
pub fn send(&self, value: T) -> Result<(), SendError<T>> {
if self.chan.is_closed() {
return Err(SendError(value));
}
self.chan.push(value);
Ok(())
}
pub async fn closed(&self) {
self.chan.closed().await;
}
pub fn is_closed(&self) -> bool {
self.chan.is_closed()
}
pub fn same_channel(&self, other: &Self) -> bool {
Rc::ptr_eq(&self.chan, &other.chan)
}
}
impl<T> Clone for UnboundedSender<T> {
fn clone(&self) -> Self {
self.chan.add_sender();
Self {
chan: Rc::clone(&self.chan),
}
}
}
impl<T> Drop for UnboundedSender<T> {
fn drop(&mut self) {
self.chan.drop_sender();
}
}
impl<T> fmt::Debug for UnboundedSender<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("UnboundedSender")
.field("closed", &self.is_closed())
.finish()
}
}
pub struct UnboundedReceiver<T> {
chan: Rc<Chan<T, Unbounded>>,
}
impl<T> UnboundedReceiver<T> {
receiver_methods!();
}
impl<T> Drop for UnboundedReceiver<T> {
fn drop(&mut self) {
self.chan.drop_rx();
}
}
impl<T> fmt::Debug for UnboundedReceiver<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("UnboundedReceiver")
.field("len", &self.len())
.field("closed", &self.is_closed())
.finish()
}
}