Async fn in traits usage scenarios

What follows are a list of "usage scenarios" for async fns in traits and some of their characteristics.

Core Rust async traits

Defining core Rust async traits like AsyncRead:

#![allow(unused)] fn main() { trait AsyncRead { async fn read(&mut self, buffer: &mut [u8]) -> usize; } }

And implementing them in client code:

#![allow(unused)] fn main() { }

Characteristics:

  • Need static dispatch with zero overhead, so folks can write fn foo<F: AsyncRead>(), have it fully monomorphized, and equally efficient
  • Need to support dyn AsyncRead eventually (people will want to do that)
  • Need ability to

Client: ship library in crates.io that leverages async traits

Example from AWS Rust SDK:

#![allow(unused)] fn main() { pub trait ProvideCredentials: Send + Sync + Debug { fn provide_credentials<'a>(&'a self) -> ProvideCredentials<'a>; } }

People implement this like

#![allow(unused)] fn main() { impl ProvideCredentials for MyType { fn provide_credentials<'a>(&'a self) -> ProvideCredentials<'a> { ProvideCredentials::new(async move { ... }) } } }

where [ProvideCredentials](https://docs.rs/aws-types/0.10.1/aws_types/credentials/future/struct.ProvideCredentials.html) is a struct that takes an impl Future` and creates

Embedded: ship library in crates.io that leverages async traits