tokio-async-await with trait
Neither async
functions nor impl Trait
are allowed in traits. You can use associated types to get closer. Here are some ideas:
pub trait ResourceTrait {
type FutType: Future<Output = ()>;
fn prepare(&mut self, auth: &str) -> Self::Next;
}
Implementing this is currently is a bit tricky, since some of the required tooling is either not yet available, stable or buggy.
It can be implemented as:
impl ResourceTrait for Resource {
type FutType = FutureObj<'static, ()>;
fn prepare(&mut self, auth: &str) -> FutureObj<'static, ()> {
FutureObj::new(Box::new(
async move {
// Do async things
// You might get a lifetime issue here if trying to access auth,
// since it's borrowed.
}
))
}
}
An alternative with existential types might be:
impl ResourceTrait for Resource {
// this is required since the real type of the async function
// is unnameable
existential type FutType = Future<Output = ()>;
fn prepare(&mut self, auth: &str) -> Self::FutType {
async move {
// Do async things. Might still encounter the same borrowing issues,
// since the lifetime of the returned Future isn't coupled to the
// lifetime of self.
// The workaround is to make copies of all required fields and move
// them into the Future
}
}
}
This might or might not work (since the feature is work in progress).
For properly borrowing parameters like self
or auth
in the returned future, we might also need Generic Associated Types to be available first.
In order to workaround the borrowing problems for self
, you might be able to define
struct Resource {
inner: Arc<ResourceInner>, // carries all actual state
}
so that you can copy inner
in prepare
and move it into the Future
.