### Install mdbook and mdbook-linkcheck Source: https://github.com/rust-lang/async-book/blob/master/README.md Install the necessary tools for building and checking the mdbook documentation. ```bash cargo install mdbook cargo install mdbook-linkcheck ``` -------------------------------- ### Async Mini-Redis Client Example in Rust Source: https://github.com/rust-lang/async-book/blob/master/src/part-guide/async-await.md Illustrates connecting to a mini-redis server, setting a key, and getting a value using async/await and the `?` operator for error handling. ```rust #[tokio::main] async fn main() -> Result<()> { // Open a connection to the mini-redis address. let mut client = client::connect("127.0.0.1:6379").await?; // Set the key "hello" with value "world" client.set("hello", "world".into()).await?; // Get key "hello" let result = client.get("hello").await?; println!("got value from the server; result={:?}", result); Ok(()) } ``` -------------------------------- ### Basic Async Hello World in Rust Source: https://github.com/rust-lang/async-book/blob/master/src/part-guide/async-await.md A fundamental 'hello, world!' example demonstrating the basic structure of an async Rust program using Tokio. ```rust use tokio::runtime; #[tokio::main] async fn main() { println!("Hello, world!"); } ``` -------------------------------- ### Sequential Code Execution Example Source: https://github.com/rust-lang/async-book/blob/master/src/part-guide/concurrency.md Illustrates the default sequential execution flow. Each line executes only after the previous one has finished. ```rust do_a_thing(); println!("hello!"); do_another_thing(); ``` -------------------------------- ### Rust Async Hello World Source: https://github.com/rust-lang/async-book/blob/master/src/intro.md A basic 'hello, world!' example demonstrating the definition and invocation of an asynchronous function using `async fn` and `.await`. No concurrency is involved. ```rust async fn main() { println!("hello, world!"); } ``` -------------------------------- ### Async Function State Machine Example Source: https://github.com/rust-lang/async-book/blob/master/src/07_workarounds/04_recursion.md Illustrates how an async function is transformed into a state machine, showing the structure for both a sequential and a recursive async function. ```rust # async fn step_one() { /* ... */ } # async fn step_two() { /* ... */ } # struct StepOne; # struct StepTwo; // This function: async fn foo() { step_one().await; step_two().await; } // generates a type like this: enum Foo { First(StepOne), Second(StepTwo), } // So this function: async fn recursive() { recursive().await; recursive().await; } // generates a type like this: enum Recursive { First(Recursive), Second(Recursive), } ``` -------------------------------- ### Async Function and Block Examples in Rust Source: https://github.com/rust-lang/async-book/blob/master/src/03_async_await/01_chapter.md Demonstrates the creation of futures using both `async fn` and `async` blocks. These futures are lazy and require an executor to run. ```rust async fn foo() -> i32 { 5 } let x = async { 10 }; // Futures are lazy and do nothing until run. // To run them, you must `.await` them. // let y = foo().await; // This would run foo() to completion. // let z = x.await; // This would run the async block to completion. ``` -------------------------------- ### Example `SocketRead` Future Source: https://github.com/rust-lang/async-book/blob/master/src/02_execution/02_future.md Illustrates a `SocketRead` future that polls for data, registering a wake-up call when data is not immediately available. ```rust struct SocketRead { // ... fields ... } impl SimpleFuture for SocketRead { type Output = Bytes; fn poll(self: Pin<&mut Self>, wake: fn()) -> Poll { // ... implementation ... Poll::Pending } } ``` -------------------------------- ### Async Sleep Example in Rust Source: https://github.com/rust-lang/async-book/blob/master/src/part-guide/async-await.md Demonstrates sequential execution in a single async task by using an async sleep function between printing messages. This highlights that concurrency is not introduced without explicit task management. ```rust use tokio::time::{sleep, Duration}; #[tokio::main] async fn main() { println!("hello"); sleep(Duration::from_secs(1)).await; println!("world"); } ``` -------------------------------- ### Serve the mdbook documentation locally Source: https://github.com/rust-lang/async-book/blob/master/README.md Launch a local web server to view the book while writing and see changes reflected. ```bash mdbook serve ``` -------------------------------- ### Async function with self-referential variable Source: https://github.com/rust-lang/async-book/blob/master/src/part-reference/pinning.md An example of an async function where a variable 'b' references another variable 'a' within the same scope. ```rust async fn foo() { let a = ...; let b = &a; bar().await; // use b } ``` -------------------------------- ### Build the mdbook documentation Source: https://github.com/rust-lang/async-book/blob/master/README.md Generate the finished book in the 'book/' directory. ```bash mdbook build ``` -------------------------------- ### `select!` with `default` and `complete` Branches Source: https://github.com/rust-lang/async-book/blob/master/src/06_multiple_futures/03_select.md Demonstrates using `default` to execute a branch immediately if no other futures are ready, and `complete` to handle the case where all selected futures have finished. ```rust async fn default_and_complete() { let mut fut1 = future::ready(1); let mut fut2 = future::ready(2); select! { default => println!("Default branch executed"), res = fut1 => println!("fut1 completed with {}", res), res = fut2 => println!("fut2 completed with {}", res), complete => println!("All futures completed"), } } ``` -------------------------------- ### Setting Up Tokio Runtime Source: https://context7.com/rust-lang/async-book/llms.txt Configures the Tokio runtime as a dependency and uses the #[tokio::main] attribute to enable an async main function. ```rust // Cargo.toml // [dependencies] // tokio = { version = "1", features = ["full"] } // Define an async function async fn say_hello() { println!("hello, world!"); } #[tokio::main] // Initializes Tokio runtime and creates initial task async fn main() { // Call an async function and await its result say_hello().await; } ``` -------------------------------- ### Illustrating Move Semantics in Rust Source: https://github.com/rust-lang/async-book/blob/master/src/part-reference/pinning.md This example demonstrates how assigning a variable to another moves the data, making the original variable invalid. This is a core concept in Rust's memory management. ```rust struct Bad { field: u64, r: &'self u64, } ``` -------------------------------- ### Using Async Functions and Await Source: https://context7.com/rust-lang/async-book/llms.txt Demonstrates defining async functions that return futures and using the await keyword to drive them to completion. ```rust // An async function that doesn't need to wait for anything async fn add(a: u32, b: u32) -> u32 { a + b } async fn wait_to_add(a: u32, b: u32) -> u32 { tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await; a + b } #[tokio::main] async fn main() { // Returns immediately with result 18 let result1 = add(15, 3).await; // Waits 1 second, allowing other tasks to run let result2 = wait_to_add(15, 3).await; println!("Results: {} and {}", result1, result2); } ``` -------------------------------- ### Concurrent Downloading with Threads Source: https://github.com/rust-lang/async-book/blob/master/src/01_getting_started/02_why_async.md Illustrates traditional thread-based concurrency for downloading two web pages. This approach spawns a new thread for each task, which can be resource-intensive for small tasks. ```rust fn get_two_sites() -> Result<()>{ let mut handles = vec![]; for url in ["http://www.google.com", "http://www.rust-lang.org"] { handles.push(thread::spawn(move || { let mut resp = reqwest::blocking::get(url).unwrap(); println!("{}: {}", url, resp.text().unwrap().len()); })); } for handle in handles { handle.join().unwrap(); } Ok(()) } ``` -------------------------------- ### Setting up a Readable Callback for a Socket Source: https://github.com/rust-lang/async-book/blob/master/src/02_execution/05_io.md This pseudocode illustrates how a `Socket` type might use an IO blocker to set up a callback for when the socket becomes readable. It registers the socket's interest with the executor's IO event map. ```rust impl Socket { fn set_readable_callback(&self, waker: Waker) { // `local_executor` is a reference to the local executor. // This could be provided at creation of the socket, but in practice // many executor implementations pass it down through thread local // storage for convenience. let local_executor = self.local_executor; // Unique ID for this IO object. let id = self.id; // Store the local waker in the executor's map so that it can be called // once the IO event arrives. local_executor.event_map.insert(id, waker); local_executor.add_io_event_interest( &self.socket_file_descriptor, Event { id, signals: READABLE }, ); } } ``` -------------------------------- ### Pinning Futures in Rust Source: https://context7.com/rust-lang/async-book/llms.txt Demonstrates pinning futures using pin! macro, Box::pin for heap allocation, and reborrowing pinned references in methods. ```rust use std::pin::pin; use tokio::select; async fn my_future() -> i32 { 42 } async fn example() { // Pin a future for use in select! let fut = pin!(my_future()); select! { result = fut => println!("Got: {}", result), } } // Box::pin for heap allocation use std::pin::Pin; use std::future::Future; fn boxed_future() -> Pin + Send>> { Box::pin(async { 42 }) } // Working with pinned self in methods use std::pin::Pin; struct MyFuture; impl MyFuture { fn method(self: Pin<&mut Self>) { // Implementation } fn call_method_twice(mut self: Pin<&mut Self>) { // Use as_mut() for reborrowing pinned references self.as_mut().method(); self.as_mut().method(); } } ``` -------------------------------- ### Illustrative IO Blocker Interface Source: https://github.com/rust-lang/async-book/blob/master/src/02_execution/05_io.md This pseudocode demonstrates a typical interface for an IO blocker that integrates with system primitives. It shows how to register interest in IO events and block until one occurs. ```rust struct IoBlocker { /* ... */ } struct Event { // An ID uniquely identifying the event that occurred and was listened for. id: usize, // A set of signals to wait for, or which occurred. signals: Signals, } impl IoBlocker { /// Create a new collection of asynchronous IO events to block on. fn new() -> Self { /* ... */ } /// Express an interest in a particular IO event. fn add_io_event_interest( &self, /// The object on which the event will occur io_object: &IoObject, /// A set of signals that may appear on the `io_object` for /// which an event should be triggered, paired with /// an ID to give to events that result from this interest. event: Event, ) { /* ... */ } /// Block until one of the events occurs. fn block(&self) -> Event { /* ... */ } } let mut io_blocker = IoBlocker::new(); io_blocker.add_io_event_interest( &socket_1, Event { id: 1, signals: READABLE }, ); io_blocker.add_io_event_interest( &socket_2, Event { id: 2, signals: READABLE | WRITABLE }, ); let event = io_blocker.block(); // prints e.g. "Socket 1 is now READABLE" if socket one became readable. println!("Socket {:?} is now {:?}", event.id, event.signals); ``` -------------------------------- ### Execute futures in main Source: https://github.com/rust-lang/async-book/blob/master/src/02_execution/04_executor.md Demonstrate running async code and custom futures using the implemented executor. ```rust {{#include ../../examples/02_04_executor/src/lib.rs:main}} ``` -------------------------------- ### Using pin_project! macro from pin-project-lite Source: https://github.com/rust-lang/async-book/blob/master/src/part-reference/pinning.md The `pin_project!` declarative macro from the `pin-project-lite` crate offers a similar functionality to `pin-project` but without the dependency on procedural macros. It's a lightweight alternative. ```rust use pin_project_lite::pin_project; pin_project! { struct SomeStruct { #[pin] field1: u8, field2: bool, } } fn main() { let mut s = SomeStruct { field1: 1, field2: false }; let pinned_s = Pin::new(&mut s); let mut proj = pinned_s.project(); // proj.field1 is a Pin<&mut u8> // proj.field2 is a &mut bool *proj.field1 += 1; *proj.field2 = true; } ``` -------------------------------- ### Spawn and join async tasks with Tokio Source: https://github.com/rust-lang/async-book/blob/master/src/part-guide/async-await.md Spawn new tasks and use `JoinHandle` to wait for their completion and retrieve their results. This is analogous to joining threads. ```rust let handle = tokio::spawn(async { // ... async code ... "result" }); let result = handle.await.unwrap(); ``` -------------------------------- ### Sequential Await Pattern Source: https://github.com/rust-lang/async-book/blob/master/src/06_multiple_futures/02_join.md Demonstrates the naive approach of awaiting futures in series, which results in slower execution. ```rust {{#include ../../examples/06_02_join/src/lib.rs:naiive}} ``` -------------------------------- ### Configure Tokio Dependency Source: https://github.com/rust-lang/async-book/blob/master/src/part-guide/async-await.md Add the Tokio crate to your Cargo.toml file to enable async runtime support. ```toml [dependencies] tokio = { version = "1", features = ["full"] } ``` -------------------------------- ### Control Flow with Async Blocks Source: https://github.com/rust-lang/async-book/blob/master/src/part-guide/more-async-await.md Demonstrates how `return` is used within an async block to exit the block and continue the surrounding loop, unlike `break` or `continue` which are not directly supported. ```rust loop { { if ... { // ok continue; } } async { if ... { // not ok // continue; // ok - continues with the next execution of the `loop`, though note that if there was // code in the loop after the async block that would be executed. return; } }.await } ``` -------------------------------- ### Composing Futures with `join` Source: https://github.com/rust-lang/async-book/blob/master/src/02_execution/02_future.md Demonstrates how to run multiple futures simultaneously without requiring separate allocations, using a `join` pattern. ```rust struct Join { a: MaybeUninit, b: MaybeUninit, } impl SimpleFuture for Join where FutureA: SimpleFuture, FutureB: SimpleFuture, FutureA::Output: Unpin, FutureB::Output: Unpin, { type Output = (FutureA::Output, FutureB::Output); fn poll(self: Pin<&mut Self>, wake: fn()) -> Poll { // ... implementation ... Poll::Pending } } ``` -------------------------------- ### Configure async-std dependencies Source: https://github.com/rust-lang/async-book/blob/master/src/09_example/01_running_async_code.md Enables the attributes feature in Cargo.toml to support the async main function macro. ```toml [dependencies.async-std] version = "1.6" features = ["attributes"] ``` -------------------------------- ### Chaining Futures with `and_then` Source: https://github.com/rust-lang/async-book/blob/master/src/02_execution/02_future.md Shows how to run multiple futures sequentially, where the output of one future is used as input for the next. ```rust struct AndThen { future_a: MaybeUninit, future_b: MaybeUninit, _phantom: PhantomData, } impl SimpleFuture for AndThen where FutureA: SimpleFuture, FutureB: SimpleFuture, FutureA::Output: Unpin, FutureB::Output: Unpin, { type Output = FutureB::Output; fn poll(self: Pin<&mut Self>, wake: fn()) -> Poll { // ... implementation ... Poll::Pending } } ``` -------------------------------- ### Write Unit Test for handle_connection Source: https://github.com/rust-lang/async-book/blob/master/src/09_example/03_tests.md This unit test sets up a `MockTcpStream` with initial data, runs `handle_connection`, and asserts that the correct data was written to the mock stream. It uses `#[async_std::test]` to run the asynchronous test function. ```rust #[async_std::test] async fn test_handle_connection() { let mut mock_stream = MockTcpStream { read_data: b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n".to_vec(), written_data: vec![], }; handle_connection(&mut mock_stream).await; let expected_response = b"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello, world!"; assert_eq!(mock_stream.written_data, expected_response); } ``` -------------------------------- ### Concurrent Downloading with Async Rust Source: https://github.com/rust-lang/async-book/blob/master/src/01_getting_started/02_why_async.md Demonstrates asynchronous concurrency for downloading two web pages without creating extra threads. This method is more efficient for I/O-bound tasks as it avoids thread overhead and heap allocations. ```rust async fn get_two_sites_async() -> Result<()>{ let urls = ["http://www.google.com", "http://www.rust-lang.org"]; let mut tasks = vec![]; for url in urls { tasks.push(tokio::spawn(async move { let mut resp = reqwest::get(url).await.unwrap(); println!("{}: {}", url, resp.text().await.unwrap().len()); })); } for task in tasks { task.await.unwrap(); } Ok(()) } ``` -------------------------------- ### Implement the spawn method Source: https://github.com/rust-lang/async-book/blob/master/src/02_execution/04_executor.md Add a method to the spawner to box futures and enqueue them as tasks. ```rust {{#include ../../examples/02_04_executor/src/lib.rs:spawn_fn}} ``` -------------------------------- ### Implement an asynchronous main function Source: https://github.com/rust-lang/async-book/blob/master/src/09_example/01_running_async_code.md Uses the async_std::main attribute to run an async main function and await the connection handler. ```rust {{#include ../../examples/09_02_async_tcp_server/src/main.rs:main_func}} ``` -------------------------------- ### Import required modules Source: https://github.com/rust-lang/async-book/blob/master/src/02_execution/04_executor.md Include necessary imports for the executor implementation in src/main.rs. ```rust {{#include ../../examples/02_04_executor/src/lib.rs:imports}} ``` -------------------------------- ### Build a Concurrent TCP Server with async-std Source: https://context7.com/rust-lang/async-book/llms.txt Uses TcpListener to handle incoming connections concurrently by spawning tasks for each stream. ```rust use std::fs; use futures::stream::StreamExt; use async_std::net::TcpListener; use async_std::prelude::*; use async_std::task::spawn; use async_std::io::{Read, Write}; #[async_std::main] async fn main() { let listener = TcpListener::bind("127.0.0.1:7878").await.unwrap(); // Process incoming connections concurrently listener .incoming() .for_each_concurrent(/* limit */ None, |stream| async move { let stream = stream.unwrap(); spawn(handle_connection(stream)); // Spawn for parallelism }) .await; } async fn handle_connection(mut stream: impl Read + Write + Unpin) { let mut buffer = [0; 1024]; stream.read(&mut buffer).await.unwrap(); let get = b"GET / HTTP/1.1\r\n"; let (status_line, filename) = if buffer.starts_with(get) { ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") } else { ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") }; let contents = fs::read_to_string(filename).unwrap(); let response = format!("{status_line}{contents}"); stream.write(response.as_bytes()).await.unwrap(); stream.flush().await.unwrap(); } ``` -------------------------------- ### Constructor and thread spawning for Timer Source: https://github.com/rust-lang/async-book/blob/master/src/02_execution/03_wakeups.md Provides a constructor to create a new TimerFuture and spawns a new thread that sleeps for the specified duration before waking the associated task. ```rust impl TimerFuture { fn new(duration: Duration) -> Self { let shared_state = Arc::new(Mutex::new(SharedState { completed: false, waker: None, })); let shared_state_clone = Arc::clone(&shared_state); thread::spawn(move || { thread::sleep(duration); let mut shared_state = shared_state_clone.lock().unwrap(); shared_state.completed = true; if let Some(waker) = shared_state.waker.take() { waker.wake(); } }); TimerFuture { shared_state } } } ``` -------------------------------- ### Concurrently Await Futures in Rust Source: https://github.com/rust-lang/async-book/blob/master/src/01_getting_started/04_async_await_primer.md Shows how to run multiple futures concurrently using `async_std::task::spawn` and `.await`. This allows tasks like dancing to run at the same time as learning and singing. ```rust use async_std::task; async fn learn_song() -> Song { // ... Song { { "name": "Blue Moon" } } } async fn sing_song(song: Song) { // ... } async fn dance() { // ... } fn main() { let learn_handle = task::spawn(async { learn_song().await }); let _ = task::block_on(dance()); let song = task::block_on(learn_handle); task::block_on(sing_song(song)); } struct Song { name: String, } ``` -------------------------------- ### Parallel Future Composition with Spawn Source: https://github.com/rust-lang/async-book/blob/master/src/part-guide/concurrency-primitives.md Run two futures in parallel using `spawn`. The `await`s here are on `JoinHandle`s to retrieve results once futures complete. ```rust async { let a = spawn(a); let b = spawn(b); (a.await, b.await) } ``` -------------------------------- ### Configure Cargo.toml dependencies Source: https://github.com/rust-lang/async-book/blob/master/src/02_execution/04_executor.md Add the futures crate to your project to access the ArcWake trait. ```toml [package] name = "timer_future" version = "0.1.0" authors = ["XYZ Author"] edition = "2021" [dependencies] futures = "0.3" ``` -------------------------------- ### Simplified and Real Future Trait Signatures Source: https://context7.com/rust-lang/async-book/llms.txt Illustrates the conceptual `SimpleFuture` and the actual `Future` trait signature in Rust, highlighting the use of `Pin` for self-referential types and `Context` for task notification. ```rust use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; // Simplified Future trait concept trait SimpleFuture { type Output; fn poll(&mut self, wake: fn()) -> Poll; } // Real Future trait signature trait RealFuture { type Output; fn poll( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll; } ``` -------------------------------- ### Using #[pin_project] macro Source: https://github.com/rust-lang/async-book/blob/master/src/part-reference/pinning.md The `#[pin_project]` attribute macro from the `pin-project` crate helps implement safe pin projection. It generates a pinned version of the type that can be accessed via the `project` method. ```rust #[macro_use] extern crate pin_project; pin_project! { struct SomeStruct { #[pin] field1: u8, field2: bool, } } fn main() { let mut s = SomeStruct { field1: 1, field2: false }; let pinned_s = Pin::new(&mut s); let mut proj = pinned_s.project(); // proj.field1 is a Pin<&mut u8> // proj.field2 is a &mut bool *proj.field1 += 1; *proj.field2 = true; } ``` -------------------------------- ### Sequentially Await Futures in Rust Source: https://github.com/rust-lang/async-book/blob/master/src/01_getting_started/04_async_await_primer.md Demonstrates blocking on futures sequentially. This approach is less performant as it only executes one task at a time. ```rust async fn learn_song() -> Song { // ... Song { { "name": "Blue Moon" } } } async fn sing_song(song: Song) { // ... } async fn dance() { // ... } fn main() { let song = task::block_on(learn_song()); task::block_on(sing_song(song)); task::block_on(dance()); } struct Song { name: String, } ``` -------------------------------- ### Basic `select!` Usage Source: https://github.com/rust-lang/async-book/blob/master/src/06_multiple_futures/03_select.md Runs multiple futures concurrently and executes a handler when the first future completes. The remaining futures are dropped. ```rust async fn example() { let t1 = async { 1 }; let t2 = async { 2 }; select! { res = t1 => println!("t1 completed first with {}", res), res = t2 => println!("t2 completed first with {}", res), } } ``` -------------------------------- ### Serve Requests in Parallel with Tasks Source: https://github.com/rust-lang/async-book/blob/master/src/09_example/02_handling_connections_concurrently.md Spawns tasks onto separate threads using async_std::task::spawn for preemptive multitasking. ```rust {{#include ../../examples/09_05_final_tcp_server/src/main.rs:main_func}} ``` -------------------------------- ### Socket Read Future Implementation Source: https://context7.com/rust-lang/async-book/llms.txt A basic implementation of a `SimpleFuture` for reading data from a socket. It demonstrates polling for data and registering a callback when no data is immediately available. ```rust pub struct SocketRead<'a> { socket: &'a Socket, } impl SimpleFuture for SocketRead<'_> { type Output = Vec; fn poll(&mut self, wake: fn()) -> Poll { if self.socket.has_data_to_read() { // Data available - return it immediately Poll::Ready(self.socket.read_buf()) } else { // No data yet - register callback and return Pending self.socket.set_readable_callback(wake); Poll::Pending } } } ``` -------------------------------- ### Synchronous TCP Server Main Implementation Source: https://github.com/rust-lang/async-book/blob/master/src/09_example/00_intro.md The base implementation of a single-threaded TCP server in Rust. ```rust {{#include ../../examples/09_01_sync_tcp_server/src/main.rs}} ``` -------------------------------- ### Handling Recursion with Box::pin (Pre-Rust 1.77) Source: https://github.com/rust-lang/async-book/blob/master/src/07_workarounds/04_recursion.md Demonstrates the workaround for recursive async functions in Rust versions prior to 1.77, which required a non-async function returning a boxed async block. ```rust use std::future::Future; use std::pin::Pin; // This is a placeholder for the actual example code from the book. // The actual code would involve a non-async function returning a boxed future. async fn recursive_workaround() -> Pin + Send>> { Box::pin(async { // ... recursive calls using Box::pin ... }) } ``` -------------------------------- ### Interaction with `Unpin` and `FusedFuture` Source: https://github.com/rust-lang/async-book/blob/master/src/06_multiple_futures/03_select.md Illustrates the necessity of calling `.fuse()` and `pin_mut` on futures used with `select!`, as they must implement `Unpin` and `FusedFuture` traits. ```rust async fn fused_stream() { let mut a_fut = future::ready(1); let mut b_fut = future::ready(2); pin_mut!(a_fut, b_fut); select! { res = a_fut.fuse() => println!("a_fut completed with {}", res), res = b_fut.fuse() => println!("b_fut completed with {}", res), } } ``` -------------------------------- ### Converting an existing Box to a pinned Box Source: https://github.com/rust-lang/async-book/blob/master/src/part-reference/pinning.md Use `Box::into_pin` to convert an existing `Box` into a `Pin>`, pinning the object in place. ```rust let boxed_value = Box::new(5); let pinned_box = boxed_value.into_pin(); // pinned_box is of type Pin> ``` -------------------------------- ### Async Function Termination Points Source: https://github.com/rust-lang/async-book/blob/master/src/part-guide/more-async-await.md Illustrates potential points where an async function might terminate due to cancellation. These include `return` statements, the `?` operator, and `await` expressions. ```rust async fn some_function(input: Option) { let Some(input) = input else { return; // Might terminate here (`return`). }; let x = foo(input)?; let y = bar(x).await; // Might terminate here (`await`). // ... // Might terminate here (implicit return). } ``` -------------------------------- ### Add Async Dependencies to Cargo.toml Source: https://github.com/rust-lang/async-book/blob/master/src/01_getting_started/04_async_await_primer.md Include necessary dependencies for asynchronous programming in your Rust project's Cargo.toml file. ```toml [dependencies] async-std = { version = "1.16", features = ["attributes"] } ``` -------------------------------- ### Async Block vs Regular Block Source: https://github.com/rust-lang/async-book/blob/master/src/part-guide/more-async-await.md Compares a regular block evaluating to a string with an async block evaluating to a future. The async block's code is not executed until awaited. ```rust let s1 = { let a = 42; format!("The answer is {a}") }; let s2 = async { let q = question().await; format!("The question is {q}") }; ``` -------------------------------- ### Define Async Main Function Source: https://github.com/rust-lang/async-book/blob/master/src/part-guide/async-await.md Use the tokio::main attribute to allow the main function to be asynchronous. ```rust #[tokio::main] async fn main() { ... } ``` -------------------------------- ### Pinning an object on the heap with Box::pin Source: https://github.com/rust-lang/async-book/blob/master/src/part-reference/pinning.md Use `Box::pin` to create a pinned `Box` for an object on the heap. This results in a `Pin>`. ```rust let mut boxed_value = Box::new(5); let pinned_box = Box::pin(boxed_value); // pinned_box is of type Pin> ``` -------------------------------- ### Concurrent Execution with join! and try_join! Source: https://context7.com/rust-lang/async-book/llms.txt Use join! to run futures concurrently on the same thread. Use try_join! when futures return Result types to fail fast on the first error. ```rust use futures::join; struct Book; struct Music; async fn get_book() -> Book { Book } async fn get_music() -> Music { Music } // WRONG: Sequential execution async fn get_book_and_music_sequential() -> (Book, Music) { let book = get_book().await; // Waits for completion let music = get_music().await; // Then starts this (book, music) } // RIGHT: Concurrent execution with join! async fn get_book_and_music_concurrent() -> (Book, Music) { let book_fut = get_book(); let music_fut = get_music(); join!(book_fut, music_fut) // Both run concurrently } // With error handling using try_join! use futures::try_join; async fn get_book_result() -> Result { Ok(Book) } async fn get_music_result() -> Result { Ok(Music) } async fn get_book_and_music_try() -> Result<(Book, Music), String> { let book_fut = get_book_result(); let music_fut = get_music_result(); try_join!(book_fut, music_fut) // Fails fast if either returns Err } ``` -------------------------------- ### Iterate Stream with `while let` and `next` in Rust Source: https://github.com/rust-lang/async-book/blob/master/src/05_streams/02_iteration_and_concurrency.md Use `while let` with the `next` method for imperative-style iteration over a stream when sequential processing is sufficient. Ensure the stream is properly initialized. ```rust let mut stream = stream.into_stream(); while let Some(item) = stream.next().await { // process item } ```