I'm trying to implement a really basic Future. Essentially, it wraps single value, while None
the future is Pending
, once Some
it's Ready
. The idea being I return the future and in some async block I modify this wrapped value so the returned Future then resolves.
I'm trying to take()
the value out of the Option
, but I get the following error. I (think?) get the gist, I'm trying to modify a Pin
ned value.
cannot borrow data in a dereference of `Pin<&mut ExampleFuture<A>>` as mutable
trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&mut ExampleFuture<A>>`
I don't really understand what I'm meant to do to get around this though. Every example using take()
I can find uses an old model of Futures or simplified versions without Pin
and so doesn't have any issues. Am I perhaps just approaching this the wrong way and take()
isn't the right method? Is there a far better approach?
The reason I'm doing this is the function I'm trying to write returns a Stream and Future. It's a wrapper around an HTTP API, results are paginated (hence the Stream) but the first page of results has additional metrics I want to return in the Future. Happy to provide more detail if helpful.
Minimal & highly contrived example:
use futures::Future;
use std::{
pin::Pin,
task::{Context, Poll},
};
struct ExampleFuture<A> {
result: Option<A>,
}
impl<A> Future for ExampleFuture<A> {
type Output = A;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if let Some(result) = self.result.take() {
Poll::Ready(result)
}
else {
Poll::Pending
}
}
}
async fn example() -> impl Future<Output = usize> {
let mut future: ExampleFuture<usize> = ExampleFuture { result: None };
async {
// in my full use case this block is within `stream::try_unfold`
future.result = Some(42);
};
future
}