Repository: tokio-rs/tokio
File: tokio/src/macros/select.rs (Rust)

Code before:
        /// async fn main() {
        ///     // open our IO types
        ///     let mut file = File;
        ///     let mut channel = Channel;
        ///     let mut socket = Socket;
        ///
        ///     loop {
        ///         tokio::select! {
        ///             _ = read_send(&mut file, &mut channel) => { /* ... */ },
        ///             data = socket.read_packet() => { /* ... */ }
        ///         }
        ///     }
        /// }
        /// ```
        ///
        /// ### Moving to `merge`
        ///
        /// By using merge, you can unify multiple asynchronous tasks into a single stream,
        /// eliminating the need to manage tasks manually and reducing the risk of
        /// unintended behavior like data loss.
        ///
        /// ```ignore
        /// use std::pin::pin;
        ///
        /// use futures_concurrency::stream::{Merge, StreamExt as _};
        /// use futures_lite::stream::{unfold, StreamExt as _};
        ///
        /// struct File;
        /// struct Channel;
        /// struct Socket;
        ///
        /// impl Socket {
        ///     async fn read_packet(&mut self) -> Vec<u8> {
        ///         todo!()
        ///     }
        /// }
        ///
        /// async fn read_send(file: &mut File, channel: &mut Channel) {
        ///     // do work that is not cancel safe
        /// }
        ///
        /// enum Message {
        ///     None,
        ///     Data(Vec<u8>),
        /// }
        ///
        /// #[tokio::main]
        /// async fn main() {
        ///     // open our IO types
        ///     let mut file = File;
        ///     let mut channel = Channel;

Review comment (suggestion):
If we're going to have an example of using `merge`, then it should use the one from tokio-stream. 

Code after:
        ///         v = stream1.next() => v.unwrap(),
        ///         v = stream2.next() => v.unwrap(),
        ///     };
        ///
        ///     assert!(next == 1 || next == 4);
        /// }
        /// ```
        ///
        /// Collect the contents of two streams. In this example, we rely on pattern
        /// matching and the fact that `stream::iter` is "fused", i.e. once the stream
        /// is complete, all calls to `next()` return `None`.
        ///
        /// ```
        /// use tokio_stream::{self as stream, StreamExt};
        ///
        /// #[tokio::main]
        /// async fn main() {
        ///     let mut stream1 = stream::iter(vec![1, 2, 3]);
        ///     let mut stream2 = stream::iter(vec![4, 5, 6]);
        ///
        ///     let mut values = vec![];
        ///
        ///     loop {
        ///         tokio::select! {
        ///             Some(v) = stream1.next() => values.push(v),
        ///             Some(v) = stream2.next() => values.push(v),
        ///             else => break,
        ///         }
        ///     }
        ///
        ///     values.sort();
        ///     assert_eq!(&[1, 2, 3, 4, 5, 6], &values[..]);
        /// }
        /// ```
        ///
        /// Using the same future in multiple `select!` expressions can be done by passing
        /// a reference to the future. Doing so requires the future to be [`Unpin`]. A
        /// future can be made [`Unpin`] by either using [`Box::pin`] or stack pinning.
        ///
        /// [`Unpin`]: std::marker::Unpin
        /// [`Box::pin`]: std::boxed::Box::pin
        ///
        /// Here, a stream is consumed for at most 1 second.
        ///
        /// ```
        /// use tokio_stream::{self as stream, StreamExt};
        /// use tokio::time::{self, Duration};
        ///
        /// #[tokio::main]
        /// async fn main() {
        ///     let mut stream = stream::iter(vec![1, 2, 3]);