use core::fmt;
#[doc(no_inline)]
pub use core::future::Future;
use core::marker::PhantomData;
use core::pin::Pin;
use pin_project_lite::pin_project;
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
#[cfg(not(feature = "std"))]
use core::task::{Context, Poll};
#[cfg(feature = "std")]
use core::cell::RefCell;
#[cfg(feature = "std")]
use core::task::{Context, Poll, Waker};
#[cfg(feature = "std")]
use parking::Parker;
#[cfg(feature = "std")]
use waker_fn::waker_fn;
#[cfg(feature = "std")]
use crate::pin;
#[cfg(feature = "std")]
pub fn block_on<T>(future: impl Future<Output = T>) -> T {
pin!(future);
fn parker_and_waker() -> (Parker, Waker) {
let parker = Parker::new();
let unparker = parker.unparker();
let waker = waker_fn(move || {
unparker.unpark();
});
(parker, waker)
}
thread_local! {
static CACHE: RefCell<(Parker, Waker)> = RefCell::new(parker_and_waker());
}
CACHE.with(|cache| {
match cache.try_borrow_mut() {
Ok(cache) => {
let (parker, waker) = &*cache;
let cx = &mut Context::from_waker(&waker);
loop {
match future.as_mut().poll(cx) {
Poll::Ready(output) => return output,
Poll::Pending => parker.park(),
}
}
}
Err(_) => {
let (parker, waker) = parker_and_waker();
let cx = &mut Context::from_waker(&waker);
loop {
match future.as_mut().poll(cx) {
Poll::Ready(output) => return output,
Poll::Pending => parker.park(),
}
}
}
}
})
}
pub fn pending<T>() -> Pending<T> {
Pending {
_marker: PhantomData,
}
}
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Pending<T> {
_marker: PhantomData<T>,
}
impl<T> Unpin for Pending<T> {}
impl<T> fmt::Debug for Pending<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Pending").finish()
}
}
impl<T> Future for Pending<T> {
type Output = T;
fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<T> {
Poll::Pending
}
}
pub fn poll_once<T, F>(f: F) -> PollOnce<F>
where
F: Future<Output = T>,
{
PollOnce { f }
}
pin_project! {
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct PollOnce<F> {
#[pin]
f: F,
}
}
impl<F> fmt::Debug for PollOnce<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PollOnce").finish()
}
}
impl<T, F> Future for PollOnce<F>
where
F: Future<Output = T>,
{
type Output = Option<T>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut this = self.project();
match Pin::new(&mut this.f).poll(cx) {
Poll::Ready(t) => Poll::Ready(Some(t)),
Poll::Pending => Poll::Ready(None),
}
}
}
pub fn poll_fn<T, F>(f: F) -> PollFn<F>
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
{
PollFn { f }
}
pin_project! {
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct PollFn<F> {
f: F,
}
}
impl<F> fmt::Debug for PollFn<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PollFn").finish()
}
}
impl<T, F> Future for PollFn<F>
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
{
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
let this = self.project();
(this.f)(cx)
}
}
pub fn ready<T>(val: T) -> Ready<T> {
Ready(Some(val))
}
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Ready<T>(Option<T>);
impl<T> Unpin for Ready<T> {}
impl<T> Future for Ready<T> {
type Output = T;
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
Poll::Ready(self.0.take().expect("`Ready` polled after completion"))
}
}
pub fn yield_now() -> YieldNow {
YieldNow(false)
}
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct YieldNow(bool);
impl Future for YieldNow {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if !self.0 {
self.0 = true;
cx.waker().wake_by_ref();
Poll::Pending
} else {
Poll::Ready(())
}
}
}
pub fn zip<F1, F2>(future1: F1, future2: F2) -> Zip<F1, F2>
where
F1: Future,
F2: Future,
{
Zip {
future1: future1,
output1: None,
future2: future2,
output2: None,
}
}
pin_project! {
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Zip<F1, F2>
where
F1: Future,
F2: Future,
{
#[pin]
future1: F1,
output1: Option<F1::Output>,
#[pin]
future2: F2,
output2: Option<F2::Output>,
}
}
impl<F1, F2> Future for Zip<F1, F2>
where
F1: Future,
F2: Future,
{
type Output = (F1::Output, F2::Output);
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
if this.output1.is_none() {
if let Poll::Ready(out) = this.future1.poll(cx) {
*this.output1 = Some(out);
}
}
if this.output2.is_none() {
if let Poll::Ready(out) = this.future2.poll(cx) {
*this.output2 = Some(out);
}
}
if this.output1.is_some() && this.output2.is_some() {
Poll::Ready((this.output1.take().unwrap(), this.output2.take().unwrap()))
} else {
Poll::Pending
}
}
}
pub fn try_zip<T1, T2, E, F1, F2>(future1: F1, future2: F2) -> TryZip<F1, F2>
where
F1: Future<Output = Result<T1, E>>,
F2: Future<Output = Result<T2, E>>,
{
TryZip {
future1: future1,
output1: None,
future2: future2,
output2: None,
}
}
pin_project! {
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct TryZip<F1, F2>
where
F1: Future,
F2: Future,
{
#[pin]
future1: F1,
output1: Option<F1::Output>,
#[pin]
future2: F2,
output2: Option<F2::Output>,
}
}
impl<T1, T2, E, F1, F2> Future for TryZip<F1, F2>
where
F1: Future<Output = Result<T1, E>>,
F2: Future<Output = Result<T2, E>>,
{
type Output = Result<(T1, T2), E>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
if this.output1.is_none() {
if let Poll::Ready(out) = this.future1.poll(cx) {
match out {
Ok(t) => *this.output1 = Some(Ok(t)),
Err(err) => return Poll::Ready(Err(err)),
}
}
}
if this.output2.is_none() {
if let Poll::Ready(out) = this.future2.poll(cx) {
match out {
Ok(t) => *this.output2 = Some(Ok(t)),
Err(err) => return Poll::Ready(Err(err)),
}
}
}
if this.output1.is_some() && this.output2.is_some() {
let res1 = this.output1.take().unwrap();
let res2 = this.output2.take().unwrap();
let t1 = res1.map_err(|_| unreachable!()).unwrap();
let t2 = res2.map_err(|_| unreachable!()).unwrap();
Poll::Ready(Ok((t1, t2)))
} else {
Poll::Pending
}
}
}
pub fn or<T, F1, F2>(future1: F1, future2: F2) -> Or<F1, F2>
where
F1: Future<Output = T>,
F2: Future<Output = T>,
{
Or { future1, future2 }
}
pin_project! {
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Or<F1, F2> {
#[pin]
future1: F1,
#[pin]
future2: F2,
}
}
impl<T, F1, F2> Future for Or<F1, F2>
where
F1: Future<Output = T>,
F2: Future<Output = T>,
{
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
if let Poll::Ready(t) = this.future1.poll(cx) {
return Poll::Ready(t);
}
if let Poll::Ready(t) = this.future2.poll(cx) {
return Poll::Ready(t);
}
Poll::Pending
}
}
#[cfg(feature = "std")]
pub fn race<T, F1, F2>(future1: F1, future2: F2) -> Race<F1, F2>
where
F1: Future<Output = T>,
F2: Future<Output = T>,
{
Race { future1, future2 }
}
#[cfg(feature = "std")]
pin_project! {
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Race<F1, F2> {
#[pin]
future1: F1,
#[pin]
future2: F2,
}
}
#[cfg(feature = "std")]
impl<T, F1, F2> Future for Race<F1, F2>
where
F1: Future<Output = T>,
F2: Future<Output = T>,
{
type Output = T;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
if fastrand::bool() {
if let Poll::Ready(t) = this.future1.poll(cx) {
return Poll::Ready(t);
}
if let Poll::Ready(t) = this.future2.poll(cx) {
return Poll::Ready(t);
}
} else {
if let Poll::Ready(t) = this.future2.poll(cx) {
return Poll::Ready(t);
}
if let Poll::Ready(t) = this.future1.poll(cx) {
return Poll::Ready(t);
}
}
Poll::Pending
}
}
pub type Boxed<T> = Pin<Box<dyn Future<Output = T> + Send + 'static>>;
pub type BoxedLocal<T> = Pin<Box<dyn Future<Output = T> + 'static>>;
pub trait FutureExt: Future {
fn or<F>(self, other: F) -> Or<Self, F>
where
Self: Sized,
F: Future<Output = Self::Output>,
{
Or {
future1: self,
future2: other,
}
}
#[cfg(feature = "std")]
fn race<F>(self, other: F) -> Race<Self, F>
where
Self: Sized,
F: Future<Output = Self::Output>,
{
Race {
future1: self,
future2: other,
}
}
fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where
Self: Sized + Send + 'a,
{
Box::pin(self)
}
fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where
Self: Sized + 'a,
{
Box::pin(self)
}
}
impl<F: Future + ?Sized> FutureExt for F {}