// This exercise demonstrates async message-passing concurrency using a channel. use std::time::Duration; struct Queue { first_half: Vec, second_half: Vec, } impl Queue { fn new() -> Self { Self { first_half: vec![ String::from("winter"), String::from("is"), String::from("really"), String::from("coming"), ], second_half: vec![ String::from("we"), String::from("do"), String::from("not"), String::from("sow"), ], } } } async fn transmit(q: Queue, tx: trpl::Sender) { // Clone the sender `tx` first. let tx_clone = tx.clone(); let tx_fut1 = async move { for val in q.first_half { // Then we use the clone here tx_clone.send(val).unwrap(); trpl::sleep(Duration::from_millis(250)).await; } }; let tx_fut2 = async move { for val in q.second_half { // And here we use the original sender `tx` tx.send(val).unwrap(); trpl::sleep(Duration::from_millis(500)).await; } }; trpl::join(tx_fut1, tx_fut2).await; } fn main() { trpl::block_on(async { let (tx, mut rx) = trpl::channel(); let queue = Queue::new(); let tx_fut = transmit(queue, tx); let rx_fut = async { while let Some(value) = rx.recv().await { println!("Received: {value:?}"); } }; trpl::join!(tx_fut, rx_fut); // OR `trpl::join(tx_fut, rx_fut).await` }); } #[cfg(test)] mod tests { use super::*; #[test] fn all_messages_are_received() { trpl::block_on(async { let (tx, mut rx) = trpl::channel(); let queue = Queue::new(); transmit(queue, tx).await; let mut received = Vec::new(); while let Some(val) = rx.recv().await { received.push(val); } received.sort(); let expected: Vec = vec!["coming", "do", "is", "not", "really", "sow", "we", "winter"] .into_iter() .map(String::from) .collect(); assert_eq!(received, expected); }); } }