futures_stable/
lib.rs

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