dprint_core/
async_runtime.rsuse std::marker::PhantomData;
use std::pin::Pin;
use std::task::Context;
use std::task::Poll;
use futures::Future;
use tokio::runtime::Handle;
use tokio::runtime::RuntimeFlavor;
pub use futures::FutureExt;
pub type LocalBoxFuture<'a, T> = futures::future::LocalBoxFuture<'a, T>;
pub use async_trait::async_trait;
pub use futures::future;
#[repr(transparent)]
pub struct JoinHandle<R> {
handle: tokio::task::JoinHandle<MaskResultAsSend<R>>,
_r: PhantomData<R>,
}
impl<R> JoinHandle<R> {
pub fn abort(&self) {
self.handle.abort()
}
}
impl<R> Future for JoinHandle<R> {
type Output = Result<R, tokio::task::JoinError>;
fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
unsafe {
let me: &mut Self = Pin::into_inner_unchecked(self);
let handle = Pin::new_unchecked(&mut me.handle);
match handle.poll(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(Ok(r)) => Poll::Ready(Ok(r.into_inner())),
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
}
}
}
}
#[inline(always)]
pub fn spawn<F: Future<Output = R> + 'static, R: 'static>(f: F) -> JoinHandle<R> {
debug_assert!(Handle::current().runtime_flavor() == RuntimeFlavor::CurrentThread);
let future = unsafe { MaskFutureAsSend::new(f) };
JoinHandle {
handle: tokio::task::spawn(future),
_r: Default::default(),
}
}
#[inline(always)]
pub fn spawn_blocking<F: (FnOnce() -> R) + Send + 'static, R: Send + 'static>(f: F) -> JoinHandle<R> {
let handle = tokio::task::spawn_blocking(|| MaskResultAsSend { result: f() });
JoinHandle {
handle,
_r: Default::default(),
}
}
#[repr(transparent)]
#[doc(hidden)]
pub struct MaskResultAsSend<R> {
result: R,
}
unsafe impl<R> Send for MaskResultAsSend<R> {}
impl<R> MaskResultAsSend<R> {
#[inline(always)]
pub fn into_inner(self) -> R {
self.result
}
}
#[repr(transparent)]
pub struct MaskFutureAsSend<F> {
future: F,
}
impl<F> MaskFutureAsSend<F> {
#[inline(always)]
pub unsafe fn new(future: F) -> Self {
Self { future }
}
}
unsafe impl<F> Send for MaskFutureAsSend<F> {}
impl<F: Future> Future for MaskFutureAsSend<F> {
type Output = MaskResultAsSend<F::Output>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<MaskResultAsSend<F::Output>> {
unsafe {
let me: &mut MaskFutureAsSend<F> = Pin::into_inner_unchecked(self);
let future = Pin::new_unchecked(&mut me.future);
match future.poll(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(result) => Poll::Ready(MaskResultAsSend { result }),
}
}
}
}
pub struct DropGuardAction<T: FnOnce()> {
finalizer: Option<T>,
}
impl<T: FnOnce()> Drop for DropGuardAction<T> {
fn drop(&mut self) {
if let Some(finalizer) = self.finalizer.take() {
(finalizer)();
}
}
}
impl<T: FnOnce()> DropGuardAction<T> {
pub fn new(finalizer: T) -> Self {
Self { finalizer: Some(finalizer) }
}
pub fn forget(&mut self) {
self.finalizer.take();
}
}