Created
May 5, 2023 08:58
-
-
Save arturaz/3159e791fed31b38730543f3df31100b to your computer and use it in GitHub Desktop.
Rust: async_trait + pin_project
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::{pin::Pin, future::Future, task::{Context, Poll}}; | |
use async_trait::async_trait; | |
use pin_project::pin_project; | |
use std::sync::Arc; | |
#[async_trait] | |
pub trait MyAsyncTrait: Send + Sync + Clone { | |
async fn my_async_fn(&self); | |
} | |
#[derive(Clone)] | |
struct MyAsyncTraitImpl {} | |
#[async_trait] | |
impl MyAsyncTrait for MyAsyncTraitImpl { | |
async fn my_async_fn(&self) { | |
println!("Hello from my_async_fn"); | |
} | |
} | |
#[pin_project] | |
pub struct MyFuture<'a, T: MyAsyncTrait + 'a> { | |
async_trait: Arc<T>, | |
#[pin] future: Option<Pin<Box<dyn Future<Output = ()> + Send + 'a>>>, | |
} | |
impl<'a, T: MyAsyncTrait> Future for MyFuture<'a, T> { | |
type Output = (); | |
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | |
let mut this = self.as_mut().project(); | |
let maybe_future = this.future.as_mut().as_pin_mut(); | |
match maybe_future { | |
None => { | |
println!("Creating future."); | |
let async_trait = this.async_trait.clone(); | |
let fut = Box::pin(async move { | |
async_trait.my_async_fn().await; | |
}); | |
this.future.set(Some(fut)); | |
// After setting the future, call poll again to start polling it. | |
self.poll(cx) | |
}, | |
Some(future) => { | |
println!("Polling future."); | |
future.poll(cx) | |
}, | |
} | |
} | |
} | |
#[tokio::main] | |
async fn main() { | |
let async_trait = MyAsyncTraitImpl {}; | |
let my_future = MyFuture { | |
async_trait: Arc::new(async_trait), | |
future: None, | |
}; | |
println!("Starting."); | |
my_future.await; | |
println!("Done."); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment