futures_stable/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
#![no_std]
#![cfg_attr(feature = "nightly", feature(arbitrary_self_types))]
#![cfg_attr(feature = "nightly", feature(pin))]
macro_rules! if_nightly {
($($i:item)*) => ($(
#[cfg(feature = "nightly")]
$i
)*)
}
if_nightly! {
macro_rules! if_std {
($($i:item)*) => ($(
#[cfg(feature = "std")]
$i
)*)
}
extern crate futures_core;
extern crate futures_executor;
use core::mem::PinMut;
use futures_core::{Future, Stream, Poll, task};
if_std! {
extern crate std;
mod executor;
mod unsafe_pin;
use std::boxed::PinBox;
pub use executor::{StableExecutor, block_on_stable};
use unsafe_pin::UnsafePin;
}
/// A trait for `Future`s which can be pinned to a particular location in memory.
///
/// These futures take `self` by `PinMut<Self>`, rather than `&mut Self`.
/// This allows types which are not [`Unpin`](::std::marker::Unpin) to guarantee
/// that they won't be moved after being polled. Since they won't be moved, it's
/// possible for them to safely contain references to themselves.
///
/// The most common examples of such self-referential `StableFuture`s are `#[async]`
/// functions and `async_block!`s.
///
/// All types which implement `Future` also implement `StableFuture` automatically.
pub trait StableFuture {
/// A successful value
type Item;
/// An error
type Error;
/// Attempt to resolve the future to a final value, registering the current task
/// for wakeup if the value is not yet available.
///
/// This method takes `self` by `PinMut`, and so calling it requires putting `Self`
/// in a [`PinBox`](::std::boxed::PinBox) using the `pin` method, or otherwise
/// guaranteeing that the location of `self` will not change after a call to `poll`.
fn poll(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Self::Item, Self::Error>;
/// Pin the future to a particular location by placing it on the heap.
#[cfg(feature = "std")]
fn pin<'a>(self) -> PinBox<Future<Item = Self::Item, Error = Self::Error> + Send + 'a>
where Self: Send + Sized + 'a
{
PinBox::new(unsafe { UnsafePin::new(self) })
}
/// Pin the future to a particular location by placing it on the heap.
///
/// This method is the same as `pin`, but doesn't require that `Self` can be
/// safely sent across threads. `pin` should be preferred where possible.
#[cfg(feature = "std")]
fn pin_local<'a>(self) -> PinBox<Future<Item = Self::Item, Error = Self::Error> + 'a>
where Self: Sized + 'a
{
PinBox::new(unsafe { UnsafePin::new(self) })
}
}
impl<F: Future> StableFuture for F {
type Item = F::Item;
type Error = F::Error;
fn poll(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Self::Item, Self::Error> {
F::poll(unsafe { PinMut::get_mut_unchecked(self) }, ctx)
}
}
/// A trait for `Stream`s which can be pinned to a particular location in memory.
///
/// These streams take `self` by `PinMut<Self>`, rather than `&mut Self`.
/// This allows types which are not [`Unpin`](::std::marker::Unpin) to guarantee
/// that they won't be moved after being polled. Since they won't be moved, it's
/// possible for them to safely contain references to themselves.
///
/// The most common examples of such self-referential `StableStream`s are
/// `#[async_stream(item = Foo)]` functions.
///
/// All types which implement `Stream` also implement `StableStream` automatically.
pub trait StableStream {
/// A successful value
type Item;
/// An error
type Error;
/// Attempt to resolve the stream to the next value, registering the current task
/// for wakeup if the value is not yet available.
///
/// This method takes `self` by `PinMut`, and so calling it requires putting `Self`
/// in a [`PinBox`](::std::boxed::PinBox) using the `pin` method, or otherwise
/// guaranteeing that the location of `self` will not change after a call to `poll`.
fn poll_next(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error>;
/// Pin the stream to a particular location by placing it on the heap.
#[cfg(feature = "std")]
fn pin<'a>(self) -> PinBox<Stream<Item = Self::Item, Error = Self::Error> + Send + 'a>
where Self: Send + Sized + 'a
{
PinBox::new(unsafe { UnsafePin::new(self) })
}
/// Pin the stream to a particular location by placing it on the heap.
///
/// This method is the same as `pin`, but doesn't require that `Self` can be
/// safely sent across threads. `pin` should be preferred where possible.
#[cfg(feature = "std")]
fn pin_local<'a>(self) -> PinBox<Stream<Item = Self::Item, Error = Self::Error> + 'a>
where Self: Sized + 'a
{
PinBox::new(unsafe { UnsafePin::new(self) })
}
}
impl<S: Stream> StableStream for S {
type Item = S::Item;
type Error = S::Error;
fn poll_next(self: PinMut<Self>, ctx: &mut task::Context) -> Poll<Option<Self::Item>, Self::Error> {
S::poll_next(unsafe { PinMut::get_mut_unchecked(self) }, ctx)
}
}
}