rustbook_learning_guide/
async_programming.rs

1//! # Asynchronous Programming
2//! 
3//! ## Understanding Async/Await
4//! 
5//! Asynchronous programming allows you to write concurrent code that can handle many tasks
6//! simultaneously without blocking. Rust's async/await syntax makes it easier to write
7//! asynchronous code that looks and feels like synchronous code.
8//! 
9//! ### Key Concepts:
10//! 
11//! #### Futures
12//! - A `Future` represents a value that might not be available yet
13//! - Futures are lazy - they don't do anything until polled
14//! - The `Future` trait is the foundation of async programming in Rust
15//! 
16//! #### async/await
17//! - `async` functions return a `Future`
18//! - `await` is used to wait for a `Future` to complete
19//! - `await` can only be used inside `async` functions
20//! 
21//! #### Executors
22//! - Executors are responsible for running futures to completion
23//! - Popular executors: `tokio`, `async-std`, `smol`
24//! 
25//! ## Common Async Patterns
26//! 
27//! - **Concurrent execution**: Running multiple futures simultaneously
28//! - **Sequential execution**: Waiting for one future before starting the next
29//! - **Timeouts**: Setting time limits on operations
30//! - **Error handling**: Dealing with errors in async contexts
31//! 
32//! ## Async Traits and Types
33//! 
34//! - `Future`: The core trait for asynchronous computation
35//! - `Stream`: Asynchronous iterator
36//! - `Sink`: Asynchronous writer
37//! - `AsyncRead`/`AsyncWrite`: Asynchronous I/O traits
38
39use std::future::Future;
40use std::pin::Pin;
41use std::task::{Context, Poll};
42use std::time::Duration;
43
44/// A simple future that completes after a delay
45pub struct DelayFuture {
46    duration: Duration,
47    start_time: Option<std::time::Instant>,
48}
49
50impl DelayFuture {
51    pub fn new(duration: Duration) -> Self {
52        DelayFuture {
53            duration,
54            start_time: None,
55        }
56    }
57}
58
59impl Future for DelayFuture {
60    type Output = ();
61    
62    fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
63        let start_time = self.start_time.get_or_insert_with(std::time::Instant::now);
64        
65        if start_time.elapsed() >= self.duration {
66            Poll::Ready(())
67        } else {
68            Poll::Pending
69        }
70    }
71}
72
73/// A custom future that yields a value after some computation
74pub struct ComputeFuture {
75    value: Option<i32>,
76}
77
78impl ComputeFuture {
79    pub fn new(value: i32) -> Self {
80        ComputeFuture { value: Some(value) }
81    }
82}
83
84impl Future for ComputeFuture {
85    type Output = i32;
86    
87    fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
88        match self.value.take() {
89            Some(value) => {
90                // Simulate some computation
91                let result = value * 2 + 1;
92                Poll::Ready(result)
93            }
94            None => Poll::Pending,
95        }
96    }
97}
98
99/// Async programming examples
100pub fn async_examples() {
101    println!("\nโšก Async Examples");
102    println!("{}", "-".repeat(18));
103    
104    println!("Async programming concepts demonstrated");
105    println!("Use tokio or async-std for real async code");
106    
107    show_async_signatures();
108    demonstrate_future_creation();
109    show_async_patterns();
110    async_error_handling_concepts();
111}
112
113fn show_async_signatures() {
114    println!("\n๐Ÿ“‹ Async Function Signatures");
115    println!("{}", "-".repeat(30));
116    
117    println!("async fn simple_async() -> i32 {{ 42 }}");
118    println!("async fn async_with_params(x: i32, y: i32) -> i32 {{ x + y }}");
119    println!("async fn async_with_result() -> Result<String, &'static str> {{ ... }}");
120}
121
122fn demonstrate_future_creation() {
123    println!("\n๐Ÿ”ง Future Creation");
124    println!("{}", "-".repeat(20));
125    
126    let _delay_future = DelayFuture::new(Duration::from_millis(100));
127    let _compute_future = ComputeFuture::new(21);
128    
129    println!("Created DelayFuture and ComputeFuture");
130    println!("In an async runtime, these would be awaited:");
131    println!("  delay_future.await;");
132    println!("  let result = compute_future.await;");
133}
134
135fn show_async_patterns() {
136    println!("\n๐ŸŽญ Async Patterns");
137    println!("{}", "-".repeat(20));
138    
139    println!("1. Sequential execution:");
140    println!("   let a = first_async().await;");
141    println!("   let b = second_async(a).await;");
142    
143    println!("\n2. Concurrent execution:");
144    println!("   let (a, b) = tokio::join!(first_async(), second_async());");
145}
146
147fn async_error_handling_concepts() {
148    println!("\nโŒ Async Error Handling");
149    println!("{}", "-".repeat(25));
150    
151    println!("1. Result types in async functions:");
152    println!("   async fn may_fail() -> Result<i32, MyError> {{ ... }}");
153    
154    println!("\n2. Using ? operator:");
155    println!("   let value = may_fail().await?;");
156}
157
158/// Simulates an async operation that might fail
159async fn fetch_data(id: u32) -> Result<String, &'static str> {
160    if id == 0 {
161        Err("Invalid ID")
162    } else {
163        Ok(format!("Data for ID: {}", id))
164    }
165}
166
167/// Processes multiple items concurrently
168async fn process_items(items: Vec<u32>) -> Vec<Result<String, &'static str>> {
169    let mut results = Vec::new();
170    for item in items {
171        results.push(fetch_data(item).await);
172    }
173    results
174}
175
176/// Demonstrates async stream processing
177async fn process_stream() {
178    println!("\n๐ŸŒŠ Stream Processing Concepts");
179    println!("{}", "-".repeat(30));
180    
181    println!("Streams are async iterators:");
182    println!("use futures::stream::{{self, StreamExt}};");
183}
184
185/// Demonstrates async channels
186async fn channel_communication() {
187    println!("\n๐Ÿ“ก Channel Communication");
188    println!("{}", "-".repeat(25));
189    
190    println!("Async channels for communication:");
191    println!("use tokio::sync::mpsc;");
192}
193
194/// Demonstrates async traits and dynamic dispatch
195fn async_traits_concepts() {
196    println!("\n๐ŸŽฏ Async Traits");
197    println!("{}", "-".repeat(15));
198    
199    println!("Async traits (using async-trait crate):");
200    println!("#[async_trait]");
201    println!("trait AsyncProcessor {{");
202    println!("    async fn process(&self, data: &str) -> Result<String, Error>;");
203    println!("}}");
204}
205
206/// Demonstrates async testing patterns
207fn async_testing_concepts() {
208    println!("\n๐Ÿงช Async Testing");
209    println!("{}", "-".repeat(20));
210    
211    println!("Testing async functions:");
212    println!("#[tokio::test]");
213    println!("async fn test_async_function() {{");
214    println!("    let result = my_async_function().await;");
215    println!("    assert_eq!(result, expected_value);");
216    println!("}}");
217}
218
219/// Real-world async patterns
220fn real_world_patterns() {
221    println!("\n๐ŸŒ Real-World Async Patterns");
222    println!("{}", "-".repeat(35));
223    
224    println!("1. HTTP Client:");
225    println!("   let response = reqwest::get(\"https://api.example.com\")");
226    println!("       .await?");
227    println!("       .json::<MyStruct>()");
228    println!("       .await?;");
229}
230