Repository: tokio-rs/tokio
File: tokio-util/src/task/join_map.rs (Rust)

Code before:
    /// Waits until one of the tasks in the map completes and returns its
    /// output, along with the key corresponding to that task.
    ///
    /// Returns `None` if the map is empty.
    ///
    /// # Cancel Safety
    ///
    /// This method is cancel safe. If `join_next` is used as the event in a [`tokio::select!`]
    /// statement and some other branch completes first, it is guaranteed that no tasks were
    /// removed from this `JoinMap`.
    ///
    /// # Returns
    ///
    /// This function returns:
    ///
    ///  * `Some((key, Ok(value)))` if one of the tasks in this `JoinMap` has
    ///    completed. The `value` is the return value of that ask, and `key` is
    ///    the key associated with the task.
    ///  * `Some((key, Err(err))` if one of the tasks in this JoinMap` has
    ///    panicked or been aborted. `key` is the key associated  with the task
    ///    that panicked or was aborted.
    ///  * `None` if the `JoinMap` is empty.
    ///
    /// [`tokio::select!`]: tokio::select
    pub async fn join_next(&mut self) -> Option<(K, Result<V, JoinError>)> {
        let (res, id) = match self.tasks.join_next_with_id().await {
            Some(Ok((id, output))) => (Ok(output), id),
            Some(Err(e)) => {
                let id = e.id();
                (Err(e), id)
            }
            None => return None,
        };
        let key = self.remove_by_id(id)?;
        Some((key, res))
    }

    /// Aborts all tasks and waits for them to finish shutting down.
    ///
    /// Calling this method is equivalent to calling [`abort_all`] and then calling [`join_next`] in
    /// a loop until it returns `None`.
    ///
    /// This method ignores any panics in the tasks shutting down. When this call returns, the
    /// `JoinMap` will be empty.
    ///
    /// [`abort_all`]: fn@Self::abort_all
    /// [`join_next`]: fn@Self::join_next
    pub async fn shutdown(&mut self) {
        self.abort_all();
        while self.join_next().await.is_some() {}
    }

Review comment (suggestion):
we may want to add a [`#[doc(alias = ...)]` attribute](https://doc.rust-lang.org/rustdoc/advanced-features.html#add-aliases-for-an-item-in-documentation-search)
```suggestion
    #[doc(alias = "join_one")]
    pub async fn join_next(&mut self) -> Option<(K, Result<V, JoinError>)> {
```
here so that this will show up in docs searches for "join_one". i _think_ we can do this even if we also apply alice's suggestion of adding a `#[doc(hidden)]` `join_one` method.

Code after:
    /// Waits until one of the tasks in the map completes and returns its
    /// output, along with the key corresponding to that task.
    ///
    /// Returns `None` if the map is empty.
    ///
    /// # Cancel Safety
    ///
    /// This method is cancel safe. If `join_next` is used as the event in a [`tokio::select!`]
    /// statement and some other branch completes first, it is guaranteed that no tasks were
    /// removed from this `JoinMap`.
    ///
    /// # Returns
    ///
    /// This function returns:
    ///
    ///  * `Some((key, Ok(value)))` if one of the tasks in this `JoinMap` has
    ///    completed. The `value` is the return value of that ask, and `key` is
    ///    the key associated with the task.
    ///  * `Some((key, Err(err))` if one of the tasks in this JoinMap` has
    ///    panicked or been aborted. `key` is the key associated  with the task
    ///    that panicked or was aborted.
    ///  * `None` if the `JoinMap` is empty.
    ///
    /// [`tokio::select!`]: tokio::select
    #[doc(alias = "join_one")]
    pub async fn join_next(&mut self) -> Option<(K, Result<V, JoinError>)> {
        let (res, id) = match self.tasks.join_next_with_id().await {
            Some(Ok((id, output))) => (Ok(output), id),
            Some(Err(e)) => {
                let id = e.id();
                (Err(e), id)
            }
            None => return None,
        };
        let key = self.remove_by_id(id)?;
        Some((key, res))
    }

    #[doc(hidden)]
    #[deprecated(since = "0.7.4", note = "renamed to `JoinMap::join_next`.")]
    pub async fn join_one(&mut self) -> Option<(K, Result<V, JoinError>)> {
        self.join_next().await
    }

    /// Aborts all tasks and waits for them to finish shutting down.
    ///
    /// Calling this method is equivalent to calling [`abort_all`] and then calling [`join_next`] in
    /// a loop until it returns `None`.
    ///
    /// This method ignores any panics in the tasks shutting down. When this call returns, the
    /// `JoinMap` will be empty.