use futures::{future::BoxFuture, prelude::*, task::Poll};
pub struct FutureWithMetadata<F, M> {
inner_fut: BoxFuture<'static, F>,
pub metadata: M,
}
impl<F, M> FutureWithMetadata<F, M>
where
M: Unpin + Clone,
{
pub fn new(metadata: M, future: BoxFuture<'static, F>) -> Self {
Self { metadata, inner_fut: future }
}
}
impl<F, M> Future for FutureWithMetadata<F, M>
where
M: Unpin + Clone,
{
type Output = (F, M);
fn poll(
mut self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<<Self as Future>::Output> {
match self.inner_fut.poll_unpin(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(val) => Poll::Ready((val, self.metadata.clone())),
}
}
}
#[cfg(test)]
mod tests {
use {super::*, fuchsia_async as fasync, std::pin::pin, wlan_common::assert_variant};
#[fuchsia::test]
fn assign_and_read_metadata_in_future_output() {
let mut exec = fasync::TestExecutor::new();
#[derive(Debug, Clone)]
struct TestMetadata {
has_been_written: bool,
}
let test_future = FutureWithMetadata::new(
TestMetadata { has_been_written: false },
future::ready("future result").boxed(),
);
let mut test_future = pin!(test_future);
assert_eq!(test_future.metadata.has_been_written, false);
test_future.metadata.has_been_written = true;
assert_variant!(exec.run_until_stalled(&mut test_future), Poll::Ready((fut_result, metadata)) => {
assert_eq!(metadata.has_been_written, true);
assert_eq!(fut_result, "future result");
});
}
}