#![cfg(feature = "async")]
#![allow(clippy::module_name_repetitions)]
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use crate::{LogError, OSActivity};
#[must_use = "futures do nothing unless awaited or polled"]
pub struct ActivityFuture<F> {
activity: OSActivity,
future: F,
}
impl<F> ActivityFuture<F> {
pub const fn new(activity: OSActivity, future: F) -> Self {
Self { activity, future }
}
#[must_use]
pub const fn activity(&self) -> &OSActivity {
&self.activity
}
}
impl<F> ActivityFuture<F>
where
F: Future,
{
#[must_use]
pub fn into_parts(self) -> (OSActivity, F) {
(self.activity, self.future)
}
}
impl<F> Future for ActivityFuture<F>
where
F: Future,
{
type Output = Result<F::Output, LogError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = unsafe { self.get_unchecked_mut() };
let _scope = match this.activity.enter() {
Ok(scope) => scope,
Err(error) => return Poll::Ready(Err(error)),
};
unsafe { Pin::new_unchecked(&mut this.future) }
.poll(cx)
.map(Ok)
}
}
pub const fn instrument_future<F>(activity: OSActivity, future: F) -> ActivityFuture<F> {
ActivityFuture::new(activity, future)
}