Repository: tokio-rs/tokio
File: tokio/src/sync/mpsc/bounded.rs (Rust)

Code before:
    ///
    /// When multiple [`OwnedPermit`]s are needed, or the sender cannot be moved
    /// by value, it can be inexpensively cloned before calling `reserve_owned`:
    ///
    /// ```
    /// use tokio::sync::mpsc;
    ///
    /// #[tokio::main]
    /// async fn main() {
    ///     let (tx, mut rx) = mpsc::channel(1);
    ///
    ///     // Clone the sender and reserve capacity.
    ///     let permit = tx.clone().reserve_owned().await.unwrap();
    ///
    ///     // Trying to send directly on the `tx` will fail due to no
    ///     // available capacity.
    ///     assert!(tx.try_send(123).is_err());
    ///
    ///     // Sending on the permit succeeds.
    ///     permit.send(456);
    ///
    ///     // The value sent on the permit is received
    ///     assert_eq!(rx.recv().await.unwrap(), 456);
    /// }
    /// ```
    ///
    /// [`Sender::reserve`]: Sender::reserve
    /// [`OwnedPermit`]: OwnedPermit
    /// [`send`]: OwnedPermit::send
    /// [`Arc::clone`]: std::sync::Arc::clone
    pub async fn reserve_owned(self) -> Result<OwnedPermit<T>, SendError<()>> {
        self.reserve_inner(1).await?;
        Ok(OwnedPermit {
            chan: Some(self.chan),
        })
    }

    async fn reserve_inner(&self, n: usize) -> Result<(), SendError<()>> {
        crate::trace::async_trace_leaf().await;

        if n > self.max_capacity() {
            return Err(SendError(()));
        }
        match self.chan.semaphore().semaphore.acquire(n).await {
            Ok(()) => Ok(()),
            Err(_) => Err(SendError(())),
        }
    }

    /// Tries to acquire a slot in the channel without waiting for the slot to become
    /// available.

Review comment (suggestion):
This method should probably panic if `n` is greater than `self.max_capacity()`. 

Code after:
    /// use tokio::sync::mpsc;
    ///
    /// #[tokio::main]
    /// async fn main() {
    ///     let (tx, mut rx) = mpsc::channel(2);
    ///
    ///     // Reserve capacity
    ///     let mut permit = tx.reserve_many(2).await.unwrap();
    ///
    ///     // Trying to send directly on the `tx` will fail due to no
    ///     // available capacity.
    ///     assert!(tx.try_send(123).is_err());
    ///
    ///     // Sending with the permit iterator succeeds
    ///     permit.next().unwrap().send(456);
    ///     permit.next().unwrap().send(457);
    ///
    ///     // The iterator should now be exhausted
    ///     assert!(permit.next().is_none());
    ///     
    ///     // The value sent on the permit is received
    ///     assert_eq!(rx.recv().await.unwrap(), 456);
    ///     assert_eq!(rx.recv().await.unwrap(), 457);
    /// }
    /// ```
    pub async fn reserve_many(&self, n: usize) -> Result<PermitIterator<'_, T>, SendError<()>> {
        self.reserve_inner(n).await?;
        Ok(PermitIterator {
            chan: &self.chan,
            n,
        })
    }

    /// Waits for channel capacity, moving the `Sender` and returning an owned
    /// permit. Once capacity to send one message is available, it is reserved
    /// for the caller.
    ///
    /// This moves the sender _by value_, and returns an owned permit that can
    /// be used to send a message into the channel. Unlike [`Sender::reserve`],
    /// this method may be used in cases where the permit must be valid for the
    /// `'static` lifetime. `Sender`s may be cloned cheaply (`Sender::clone` is
    /// essentially a reference count increment, comparable to [`Arc::clone`]),
    /// so when multiple [`OwnedPermit`]s are needed or the `Sender` cannot be
    /// moved, it can be cloned prior to calling `reserve_owned`.
    ///
    /// If the channel is full, the function waits for the number of unreceived
    /// messages to become less than the channel capacity. Capacity to send one
    /// message is reserved for the caller. An [`OwnedPermit`] is returned to
    /// track the reserved capacity. The [`send`] function on [`OwnedPermit`]
    /// consumes the reserved capacity.
    ///