Hello dear community,
I can't implement a wrapper method for an async function. As I know an async function is a function returns an instance of std::future::Future link to async book. I'd like to implement a wrapper in order to be able to hide the struct with a trait, for a trait doesn't support async methods.
I can't designate proper lifetime bounds. The compiler says that the result's type captures lifetime that does not appear in bounds. The compiler notes that the result type captures the lifetime 'inner
.
The returned future should not have 'static
I expect because an instance of Fetch
structure doesn't live so much. With that in mind I designated an anonymous lifetime.
pub struct Fetch<'inner, D> {
inner: &'inner D
}
impl<'inner, D> Fetch<'inner, D> {
pub fn run(&mut self) -> impl Future<Output=Option<()>> + '_ {
self._run()
}
async fn _run(&mut self) -> Option<()> {
None
}
}
Then I designated lifetimes explicitly so the method definition looks so:
pub fn run<'f, 's: 'f>(&'s mut self) -> impl Future<Output=Option<()>> + 'f
As far as I know it means that the result future lives at least as long as 'f
, an instance of Fetch
lives at least as long as 's
which longer than 'f
, a reference of type D
lives at least as long as 'inner
which longer than 's
. E.g. 'inner > 's > 'f
. So the bounds are here. I would really appreciate to get an explanation of what the comiler can't get.
The code and the errors are here
P.S.
By the way it's not the first time when I stuck with lifetimes. Is there any advanced tutorial/manual/article on the internet which covers cases like this one? I read the chapters of the book which are related to lifetimes a couple of times. Still it looks like I miss something every time.
Another one question. Is there any way to desugar async code? I use cargo expand
for macros; do we have something similar for async
code?