### Async Trait Not Dyn Compatible Example Source: https://github.com/dtolnay/async-trait/blob/master/README.md Demonstrates the error encountered when trying to use a trait with an async function as a dynamic trait object. ```rust pub trait Trait { async fn f(&self); } pub fn make() -> Box { unimplemented!() } ``` ```console error[E0038]: the trait `Trait` is not dyn compatible --> src/main.rs:5:22 | 5 | pub fn make() -> Box { | ^^^^^^^^^ `Trait` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit --> src/main.rs:2:14 | 1 | pub trait Trait { | ----- this trait is not dyn compatible... 2 | async fn f(&self); | ^ ...because method `f` is `async` = help: consider moving `f` to another trait ``` -------------------------------- ### Define Async Trait with async-trait Source: https://context7.com/dtolnay/async-trait/llms.txt Annotate trait definitions and impl blocks with `#[async_trait]` to enable async methods for dynamic dispatch. This example demonstrates a basic database trait and its implementation. ```rust use async_trait::async_trait; #[async_trait] trait Database { async fn connect(&self) -> Result<(), String>; async fn query(&self, sql: &str) -> Vec; async fn disconnect(&mut self); } struct PostgresDb { connection_string: String, } #[async_trait] impl Database for PostgresDb { async fn connect(&self) -> Result<(), String> { println!("Connecting to {}", self.connection_string); Ok(()) } async fn query(&self, sql: &str) -> Vec { println!("Executing: {}", sql); vec!["row1".to_string(), "row2".to_string()] } async fn disconnect(&mut self) { println!("Disconnecting..."); } } #[tokio::main] async fn main() { let mut db = PostgresDb { connection_string: "postgres://localhost/mydb".to_string(), }; db.connect().await.unwrap(); let results = db.query("SELECT * FROM users").await; println!("Got {} results", results.len()); db.disconnect().await; } ``` -------------------------------- ### Dynamic Dispatch with Async Trait Objects Source: https://context7.com/dtolnay/async-trait/llms.txt Use `async_trait` to create trait objects (`dyn Trait`) with async methods, enabling runtime polymorphism. This example processes messages using a collection of different `MessageHandler` implementations. ```rust use async_trait::async_trait; use std::sync::Arc; #[async_trait] trait MessageHandler: Send + Sync { async fn handle(&self, message: &str) -> String; } struct EchoHandler; #[async_trait] impl MessageHandler for EchoHandler { async fn handle(&self, message: &str) -> String { format!("Echo: {}", message) } } struct UppercaseHandler; #[async_trait] impl MessageHandler for UppercaseHandler { async fn handle(&self, message: &str) -> String { message.to_uppercase() } } async fn process_messages( handlers: &[Arc], message: &str, ) -> Vec { let mut results = Vec::new(); for handler in handlers { results.push(handler.handle(message).await); } results } #[tokio::main] async fn main() { let handlers: Vec> = vec![ Arc::new(EchoHandler), Arc::new(UppercaseHandler), ]; let results = process_messages(&handlers, "hello").await; // results: ["Echo: hello", "HELLO"] for result in results { println!("{}", result); } } ``` -------------------------------- ### Fixing Elided Lifetimes in Async Functions Source: https://github.com/dtolnay/async-trait/blob/master/README.md These examples show the correct ways to define an async function within a trait using `#[async_trait]` when dealing with elided lifetimes, either by naming the lifetime explicitly or using the `'_` placeholder. ```rust #[async_trait] trait Test { // either async fn test<'e>(elided: Elided<'e>) {} // or async fn test(elided: Elided<'_>) {} } ``` -------------------------------- ### Non-Send Futures with ?Send Attribute Source: https://context7.com/dtolnay/async-trait/llms.txt Use `#[async_trait(?Send)]` when futures do not need to be `Send`, such as when using single-threaded executors or when dealing with non-`Send` types across await points. This example uses `Rc` and `RefCell` which are not `Send`. ```rust use async_trait::async_trait; use std::rc::Rc; use std::cell::RefCell; // Rc is not Send, so we need ?Send #[async_trait(?Send)] trait LocalCache { async fn get(&self, key: &str) -> Option; async fn set(&self, key: &str, value: String); } struct RcCache { data: Rc>>, } #[async_trait(?Send)] impl LocalCache for RcCache { async fn get(&self, key: &str) -> Option { self.data.borrow().get(key).cloned() } async fn set(&self, key: &str, value: String) { self.data.borrow_mut().insert(key.to_string(), value); } } // Use with a single-threaded runtime fn main() { let rt = tokio::runtime::Builder::new_current_thread() .enable_all() .build() .unwrap(); rt.block_on(async { let cache = RcCache { data: Rc::new(RefCell::new(std::collections::HashMap::new())), }; cache.set("name", "Alice".to_string()).await; let name = cache.get("name").await; println!("Name: {:?}", name); // Name: Some("Alice") }); } ``` -------------------------------- ### Implementing Async Traits with async-trait Source: https://github.com/dtolnay/async-trait/blob/master/README.md Shows how to use the `#[async_trait]` macro on traits and their implementations to enable async functions and dynamic dispatch. ```rust use async_trait::async_trait; #[async_trait] trait Advertisement { async fn run(&self); } struct Modal; #[async_trait] impl Advertisement for Modal { async fn run(&self) { self.render_fullscreen().await; for _ in 0..4u16 { remind_user_to_join_mailing_list().await; } self.hide_for_now().await; } } struct AutoplayingVideo { media_url: String, } #[async_trait] impl Advertisement for AutoplayingVideo { async fn run(&self) { let stream = connect(&self.media_url).await; stream.play().await; // Video probably persuaded user to join our mailing list! Modal.run().await; } } ``` -------------------------------- ### Mixing Async and Non-Async Methods in a Trait Source: https://context7.com/dtolnay/async-trait/llms.txt Demonstrates how to define a trait with both synchronous and asynchronous methods using the `async-trait` macro. Only async methods are transformed. ```Rust use async_trait::async_trait; #[async_trait] trait Service { // Synchronous method - not transformed fn name(&self) -> &str; // Synchronous method with default implementation fn version(&self) -> u32 { 1 } // Async methods - transformed by macro async fn start(&self) -> Result<(), String>; async fn health_check(&self) -> bool; } struct ApiService { service_name: String, } #[async_trait] impl Service for ApiService { fn name(&self) -> &str { &self.service_name } async fn start(&self) -> Result<(), String> { println!("Starting {}...", self.service_name); Ok(()) } async fn health_check(&self) -> bool { true } } #[tokio::main] async fn main() { let service = ApiService { service_name: "UserAPI".to_string(), }; println!("Service: {} v{}", service.name(), service.version()); service.start().await.unwrap(); println!("Healthy: {}", service.health_check().await); } ``` -------------------------------- ### Expanded Async Trait Implementation Source: https://github.com/dtolnay/async-trait/blob/master/README.md Illustrates the internal transformation performed by the `#[async_trait]` macro, converting async methods into futures. ```rust impl Advertisement for AutoplayingVideo { fn run<'async_trait>( &'async_trait self, ) -> Pin + Send + 'async_trait>> where Self: Sync + 'async_trait, { Box::pin(async move { /* the original method body */ }) } } ``` -------------------------------- ### Async Trait with Generics and Associated Types Source: https://context7.com/dtolnay/async-trait/llms.txt Illustrates an async trait that uses generic type parameters, associated types, and supports common traits like Send and Sync. This is useful for creating flexible data repositories. ```rust use async_trait::async_trait; #[async_trait] trait Repository { type Error: Send; async fn find_by_id(&self, id: u64) -> Result, Self::Error>; async fn save(&self, entity: &T) -> Result<(), Self::Error>; async fn delete(&self, id: u64) -> Result; } #[derive(Clone, Debug)] struct User { id: u64, name: String, } struct InMemoryUserRepo { users: std::sync::RwLock>, } #[async_trait] impl Repository for InMemoryUserRepo { type Error = String; async fn find_by_id(&self, id: u64) -> Result, Self::Error> { Ok(self.users.read().unwrap().get(&id).cloned()) } async fn save(&self, entity: &User) -> Result<(), Self::Error> { self.users.write().unwrap().insert(entity.id, entity.clone()); Ok(()) } async fn delete(&self, id: u64) -> Result { Ok(self.users.write().unwrap().remove(&id).is_some()) } } #[tokio::main] async fn main() { let repo = InMemoryUserRepo { users: std::sync::RwLock::new(std::collections::HashMap::new()), }; let user = User { id: 1, name: "Alice".to_string() }; repo.save(&user).await.unwrap(); let found = repo.find_by_id(1).await.unwrap(); println!("Found: {:?}", found); // Found: Some(User { id: 1, name: "Alice" }) repo.delete(1).await.unwrap(); let found = repo.find_by_id(1).await.unwrap(); println!("After delete: {:?}", found); // After delete: None } ``` -------------------------------- ### Async Trait with Default Retry Implementation Source: https://context7.com/dtolnay/async-trait/llms.txt Demonstrates a default implementation for a retry mechanism in an async trait. This default can be used by implementors or overridden for custom behavior. ```rust use async_trait::async_trait; #[async_trait] trait Retryable { async fn attempt(&self) -> Result; // Default implementation with retry logic async fn with_retry(&self, max_attempts: u32) -> Result { let mut last_error = String::new(); for attempt in 1..=max_attempts { match self.attempt().await { Ok(result) => return Ok(result), Err(e) => { last_error = e; println!("Attempt {} failed, retrying...", attempt); } } } Err(format!("All {} attempts failed: {}", max_attempts, last_error)) } } struct UnreliableService { fail_count: std::sync::atomic::AtomicU32, } #[async_trait] impl Retryable for UnreliableService { async fn attempt(&self) -> Result { let count = self.fail_count.fetch_add(1, std::sync::atomic::Ordering::SeqCst); if count < 2 { Err("Service unavailable".to_string()) } else { Ok("Success!".to_string()) } } // Uses default with_retry implementation } #[tokio::main] async fn main() { let service = UnreliableService { fail_count: std::sync::atomic::AtomicU32::new(0), }; let result = service.with_retry(5).await; println!("Result: {:?}", result); // Result: Ok("Success!") } ``` -------------------------------- ### Non-Threadsafe Futures with async-trait Source: https://github.com/dtolnay/async-trait/blob/master/README.md Demonstrates how to use `#[async_trait(?Send)]` to prevent `Send` and `Sync` bounds on futures when they are not required. ```rust #[async_trait] // ... trait definition ... #[async_trait(?Send)] // ... impl block ... ``` -------------------------------- ### Async Trait with Arc Self Receiver Source: https://context7.com/dtolnay/async-trait/llms.txt Shows how to use `Arc` as a receiver for async trait methods, facilitating shared ownership and safe concurrent access to trait objects. ```rust use async_trait::async_trait; use std::sync::Arc; #[async_trait] trait Worker: Send + Sync { async fn run(self: Arc); async fn status(&self) -> String; } struct BackgroundWorker { name: String, } #[async_trait] impl Worker for BackgroundWorker { async fn run(self: Arc) { println!("{} starting...", self.name); // Simulate work tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; println!("{} completed!", self.name); } async fn status(&self) -> String { format!("Worker '{}' is ready", self.name) } } #[tokio::main] async fn main() { let worker: Arc = Arc::new(BackgroundWorker { name: "DataProcessor".to_string(), }); println!("{}", worker.status().await); // Clone Arc for spawning let worker_clone = Arc::clone(&worker); tokio::spawn(async move { worker_clone.run().await; }).await.unwrap(); } ``` -------------------------------- ### Compiler Error for Implicit Elided Lifetime Source: https://github.com/dtolnay/async-trait/blob/master/README.md The compiler output shows the specific error E0726 for an implicit elided lifetime in an async function, suggesting how to fix it by indicating the anonymous lifetime. ```console error[E0726]: implicit elided lifetime not allowed here --> src/main.rs:9:29 | 9 | | ^^^^^^- help: indicate the anonymous lifetime: `<'_>` ``` -------------------------------- ### Async Function with Implicit Elided Lifetime Error Source: https://github.com/dtolnay/async-trait/blob/master/README.md This code demonstrates an error that occurs when an async function within a trait using `#[async_trait]` attempts to use an implicitly elided lifetime, which is not allowed. ```rust type Elided<'a> = &'a usize; #[async_trait] trait Test { async fn test(not_okay: Elided, okay: &usize) {} } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.