#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
#![warn(clippy::inconsistent_struct_constructor)]
#![warn(clippy::match_same_arms)]
#![warn(clippy::missing_errors_doc)]
#![warn(clippy::missing_panics_doc)]
#![warn(clippy::missing_safety_doc)]
#![warn(clippy::undocumented_unsafe_blocks)]
#![warn(missing_docs)]
#[cfg(feature = "std")]
mod alloc {
pub use std::boxed;
pub use std::collections;
pub use std::rc;
}
#[cfg(not(feature = "std"))]
extern crate alloc;
pub mod bounded;
pub mod oneshot;
pub mod semaphore;
pub mod unbounded;
mod shared;
#[cfg(feature = "std")]
use std::error;
use core::fmt;
use crate::semaphore::TryAcquireError;
const UNCOUNTED: bool = false;
const COUNTED: bool = true;
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct SendError<T>(pub T);
impl<T> fmt::Debug for SendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SendError").finish_non_exhaustive()
}
}
impl<T> fmt::Display for SendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("failed to send value, channel closed")
}
}
#[cfg(feature = "std")]
impl<T> error::Error for SendError<T> {}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TryRecvError {
Empty,
Disconnected,
}
impl TryRecvError {
pub fn is_empty(self) -> bool {
matches!(self, Self::Empty)
}
pub fn is_disconnected(self) -> bool {
matches!(self, Self::Disconnected)
}
}
impl fmt::Display for TryRecvError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Empty => f.write_str("channel is empty"),
Self::Disconnected => f.write_str("channel is closed"),
}
}
}
#[cfg(feature = "std")]
impl error::Error for TryRecvError {}
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum TrySendError<T> {
Full(T),
Closed(T),
}
impl<T> TrySendError<T> {
pub fn is_full(&self) -> bool {
matches!(self, Self::Full(_))
}
pub fn is_closed(&self) -> bool {
matches!(self, Self::Closed(_))
}
fn set<U>(self, value: U) -> TrySendError<U> {
match self {
Self::Full(_) => TrySendError::Full(value),
Self::Closed(_) => TrySendError::Closed(value),
}
}
}
impl<T> From<SendError<T>> for TrySendError<T> {
fn from(err: SendError<T>) -> Self {
Self::Closed(err.0)
}
}
impl<T> From<(TryAcquireError, T)> for TrySendError<T> {
fn from((err, elem): (TryAcquireError, T)) -> Self {
match err {
TryAcquireError::Closed => Self::Closed(elem),
TryAcquireError::NoPermits => Self::Full(elem),
}
}
}
impl<T> fmt::Debug for TrySendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut dbg = f.debug_struct("TrySendError");
match self {
Self::Full(_) => dbg.field("full", &true).finish_non_exhaustive(),
Self::Closed(_) => dbg.field("closed", &true).finish_non_exhaustive(),
}
}
}
impl<T> fmt::Display for TrySendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Full(_) => f.write_str("failed to send value, channel full"),
Self::Closed(_) => f.write_str("failed to send value, channel closed"),
}
}
}
#[cfg(feature = "std")]
impl<T> error::Error for TrySendError<T> {}
struct Mask(usize);
impl Mask {
const fn new() -> Self {
Self(0)
}
fn reset<const COUNTED: bool>(&mut self) {
if COUNTED {
self.0 += 2;
} else {
self.0 &= 0b1;
}
}
fn is_closed<const COUNTED: bool>(&self) -> bool {
if COUNTED {
self.0 & 0b1 == 1
} else {
self.0 == 1
}
}
fn close<const COUNTED: bool>(&mut self) {
if COUNTED {
self.0 |= 0b1;
} else {
self.0 = 1;
}
}
fn increase_sender_count(&mut self) {
self.0 =
self.0.checked_add(2).expect("cloning the sender would overflow the reference counter");
}
#[must_use = "must react to final sender being dropped"]
fn decrease_sender_count(&mut self) -> bool {
self.0 -= 2;
if self.0 < 2 {
return self.set_closed_bit();
}
false
}
#[cold]
fn set_closed_bit(&mut self) -> bool {
self.0 = 1;
true
}
}