#![allow(unsafe_code)]
use core::fmt;
use core::iter::FusedIterator;
use core::mem::{self, ManuallyDrop};
use core::ptr;
use super::bounded::{Bounded, Sender};
use super::chan::Chan;
#[must_use = "dropping a permit gives its slot back unused"]
pub struct Permit<'a, T> {
chan: &'a Chan<T, Bounded>,
}
impl<'a, T> Permit<'a, T> {
pub(super) fn new(chan: &'a Chan<T, Bounded>) -> Self {
Self { chan }
}
pub fn send(self, value: T) {
let chan = self.chan;
mem::forget(self);
chan.send(value);
}
}
impl<T> Drop for Permit<'_, T> {
fn drop(&mut self) {
self.chan.give_back(1);
}
}
impl<T> fmt::Debug for Permit<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Permit").finish_non_exhaustive()
}
}
#[must_use = "dropping the iterator gives its slots back unused"]
pub struct PermitIterator<'a, T> {
chan: &'a Chan<T, Bounded>,
n: usize,
}
impl<'a, T> PermitIterator<'a, T> {
pub(super) fn new(chan: &'a Chan<T, Bounded>, n: usize) -> Self {
Self { chan, n }
}
}
impl<'a, T> Iterator for PermitIterator<'a, T> {
type Item = Permit<'a, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.n == 0 {
return None;
}
self.n -= 1;
Some(Permit { chan: self.chan })
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.n, Some(self.n))
}
}
impl<T> ExactSizeIterator for PermitIterator<'_, T> {}
impl<T> FusedIterator for PermitIterator<'_, T> {}
impl<T> Drop for PermitIterator<'_, T> {
fn drop(&mut self) {
if self.n > 0 {
self.chan.give_back(self.n);
}
}
}
impl<T> fmt::Debug for PermitIterator<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PermitIterator")
.field("remaining", &self.n)
.finish()
}
}
#[must_use = "dropping a permit gives its slot back unused"]
pub struct OwnedPermit<T> {
sender: Sender<T>,
}
impl<T> OwnedPermit<T> {
pub(super) fn new(sender: Sender<T>) -> Self {
Self { sender }
}
fn into_sender(self) -> Sender<T> {
let this = ManuallyDrop::new(self);
unsafe { ptr::read(&this.sender) }
}
pub fn send(self, value: T) -> Sender<T> {
let sender = self.into_sender();
sender.chan.send(value);
sender
}
pub fn release(self) -> Sender<T> {
let sender = self.into_sender();
sender.chan.give_back(1);
sender
}
pub fn same_channel(&self, other: &Self) -> bool {
self.sender.same_channel(&other.sender)
}
pub fn same_channel_as_sender(&self, sender: &Sender<T>) -> bool {
self.sender.same_channel(sender)
}
}
impl<T> Drop for OwnedPermit<T> {
fn drop(&mut self) {
self.sender.chan.give_back(1);
}
}
impl<T> fmt::Debug for OwnedPermit<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OwnedPermit").finish_non_exhaustive()
}
}