use super::{dealloc, Channel};
use core::fmt;
use core::mem;
use core::ptr::NonNull;
pub struct SendError<T> {
channel_ptr: NonNull<Channel<T>>,
}
unsafe impl<T: Send> Send for SendError<T> {}
unsafe impl<T: Sync> Sync for SendError<T> {}
impl<T> SendError<T> {
pub(crate) const unsafe fn new(channel_ptr: NonNull<Channel<T>>) -> Self {
Self { channel_ptr }
}
#[inline]
pub fn into_inner(self) -> T {
let channel_ptr = self.channel_ptr;
mem::forget(self);
let channel: &Channel<T> = unsafe { channel_ptr.as_ref() };
let message = unsafe { channel.take_message() };
unsafe { dealloc(channel_ptr) };
message
}
#[inline]
pub fn as_inner(&self) -> &T {
unsafe { self.channel_ptr.as_ref().message().assume_init_ref() }
}
}
impl<T> Drop for SendError<T> {
fn drop(&mut self) {
unsafe {
self.channel_ptr.as_ref().drop_message();
dealloc(self.channel_ptr);
}
}
}
impl<T> fmt::Display for SendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
"sending on a closed channel".fmt(f)
}
}
impl<T> fmt::Debug for SendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SendError<{}>(_)", stringify!(T))
}
}
#[cfg(feature = "std")]
impl<T> std::error::Error for SendError<T> {}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct RecvError;
impl fmt::Display for RecvError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
"receiving on a closed channel".fmt(f)
}
}
#[cfg(feature = "std")]
impl std::error::Error for RecvError {}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum TryRecvError {
Empty,
Disconnected,
}
impl fmt::Display for TryRecvError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let msg = match self {
TryRecvError::Empty => "receiving on an empty channel",
TryRecvError::Disconnected => "receiving on a closed channel",
};
msg.fmt(f)
}
}
#[cfg(feature = "std")]
impl std::error::Error for TryRecvError {}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum RecvTimeoutError {
Timeout,
Disconnected,
}
impl fmt::Display for RecvTimeoutError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let msg = match self {
RecvTimeoutError::Timeout => "timed out waiting on channel",
RecvTimeoutError::Disconnected => "channel is empty and sending half is closed",
};
msg.fmt(f)
}
}
#[cfg(feature = "std")]
impl std::error::Error for RecvTimeoutError {}