Advertisement
Guest User

Untitled

a guest
Feb 21st, 2019
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.74 KB | None | 0 0
  1. #![feature(futures_api, async_await, await_macro)]
  2.  
  3. use core::pin::Pin;
  4. use core::future::Future;
  5. use core::task::{Waker, Poll, RawWaker, RawWakerVTable};
  6. use core::ptr::null;
  7.  
  8. struct A;
  9.  
  10. impl Future for A {
  11. type Output = String;
  12.  
  13. fn poll(self: Pin<&mut Self>, _waker: &Waker) -> Poll<Self::Output> {
  14. Poll::Ready("poll".to_string())
  15. }
  16. }
  17.  
  18. struct B {
  19. a: A,
  20. }
  21.  
  22. impl B {
  23. fn run<'a>(self: Pin<&'a mut Self>) -> impl Future<Output = String> + 'a {
  24. unsafe { Pin::new_unchecked(&mut Pin::get_unchecked_mut(self).a) }
  25. }
  26. }
  27.  
  28. async fn foo_async(mut b: B) -> String {
  29. let mut b = unsafe { Pin::new_unchecked(&mut b) };
  30. await!(b.as_mut().run()) + &await!(b.as_mut().run())
  31. }
  32.  
  33. fn foo(mut b: B) -> impl Future<Output = String> {
  34. let mut b = unsafe { Pin::new_unchecked(&mut b) };
  35. b.as_mut().run().then(move |s1| b.as_mut().run().then(move |s2| ready(s1 + &s2)))
  36. }
  37.  
  38. fn main() {
  39. println!("result: {}", wait(foo(B { a: A })));
  40. println!("result: {}", wait(foo_async(B { a: A })));
  41. }
  42.  
  43. // ------
  44.  
  45. fn wait<F>(mut future: F) -> F::Output where F: Future {
  46. let waker = noop_waker();
  47. let mut future = unsafe { Pin::new_unchecked(&mut future) };
  48. loop {
  49. if let Poll::Ready(output) = future.as_mut().poll(&waker) {
  50. return output;
  51. }
  52. }
  53. }
  54.  
  55. const NOOP_WAKER_VTABLE: RawWakerVTable = RawWakerVTable {
  56. clone: noop_clone,
  57. drop: noop,
  58. wake: noop,
  59. };
  60.  
  61. pub fn noop_waker() -> Waker {
  62. unsafe {
  63. Waker::new_unchecked(noop_raw_waker())
  64. }
  65. }
  66.  
  67. unsafe fn noop_clone(_data: *const()) -> RawWaker {
  68. noop_raw_waker()
  69. }
  70.  
  71. unsafe fn noop(_data: *const()) {
  72. }
  73.  
  74. fn noop_raw_waker() -> RawWaker {
  75. RawWaker::new(null(), &NOOP_WAKER_VTABLE)
  76. }
  77.  
  78. #[derive(Debug)]
  79. #[must_use = "futures do nothing unless polled"]
  80. pub struct Then<Fut1, Fut2, F> {
  81. chain: Chain<Fut1, Fut2, F>,
  82. }
  83.  
  84. impl<Fut1, Fut2, F> Then<Fut1, Fut2, F>
  85. where Fut1: Future,
  86. Fut2: Future,
  87. {
  88. fn new(future: Fut1, f: F) -> Then<Fut1, Fut2, F> {
  89. Then {
  90. chain: Chain::new(future, f),
  91. }
  92. }
  93.  
  94. fn chain<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut Chain<Fut1, Fut2, F>> {
  95. unsafe { Pin::new_unchecked(&mut Pin::get_unchecked_mut(self).chain) }
  96. }
  97. }
  98.  
  99. impl<Fut1, Fut2, F> Future for Then<Fut1, Fut2, F>
  100. where Fut1: Future,
  101. Fut2: Future,
  102. F: FnOnce(Fut1::Output) -> Fut2,
  103. {
  104. type Output = Fut2::Output;
  105.  
  106. fn poll(mut self: Pin<&mut Self>, waker: &Waker) -> Poll<Fut2::Output> {
  107. self.as_mut().chain().poll(waker, |output, f| f(output))
  108. }
  109. }
  110.  
  111. trait FutureExt: Future {
  112. fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
  113. where F: FnOnce(Self::Output) -> Fut,
  114. Fut: Future,
  115. Self: Sized,
  116. {
  117. Then::new(self, f)
  118. }
  119. }
  120.  
  121. impl<Fut: Future> FutureExt for Fut {
  122. }
  123. #[must_use = "futures do nothing unless polled"]
  124. #[derive(Debug)]
  125. pub(crate) enum Chain<Fut1, Fut2, Data> {
  126. First(Fut1, Option<Data>),
  127. Second(Fut2),
  128. Empty,
  129. }
  130.  
  131. impl<Fut1, Fut2, Data> Chain<Fut1, Fut2, Data> {
  132. pub(crate)fn is_terminated(&self) -> bool {
  133. if let Chain::Empty = *self { true } else { false }
  134. }
  135. }
  136.  
  137. impl<Fut1, Fut2, Data> Chain<Fut1, Fut2, Data>
  138. where Fut1: Future,
  139. Fut2: Future,
  140. {
  141. pub(crate) fn new(fut1: Fut1, data: Data) -> Chain<Fut1, Fut2, Data> {
  142. Chain::First(fut1, Some(data))
  143. }
  144.  
  145. pub(crate) fn poll<F>(
  146. self: Pin<&mut Self>,
  147. waker: &Waker,
  148. f: F,
  149. ) -> Poll<Fut2::Output>
  150. where F: FnOnce(Fut1::Output, Data) -> Fut2,
  151. {
  152. let mut f = Some(f);
  153.  
  154. // Safe to call `get_unchecked_mut` because we won't move the futures.
  155. let this = unsafe { Pin::get_unchecked_mut(self) };
  156.  
  157. loop {
  158. let (output, data) = match this {
  159. Chain::First(fut1, data) => {
  160. match unsafe { Pin::new_unchecked(fut1) }.poll(waker) {
  161. Poll::Pending => return Poll::Pending,
  162. Poll::Ready(output) => (output, data.take().unwrap()),
  163. }
  164. }
  165. Chain::Second(fut2) => {
  166. return unsafe { Pin::new_unchecked(fut2) }.poll(waker);
  167. }
  168. Chain::Empty => unreachable!()
  169. };
  170.  
  171. *this = Chain::Empty; // Drop fut1
  172. let fut2 = (f.take().unwrap())(output, data);
  173. *this = Chain::Second(fut2)
  174. }
  175. }
  176. }
  177.  
  178. #[derive(Debug, Clone)]
  179. #[must_use = "futures do nothing unless polled"]
  180. pub struct Ready<T>(Option<T>);
  181.  
  182. impl<T> Unpin for Ready<T> {}
  183.  
  184. impl<T> Future for Ready<T> {
  185. type Output = T;
  186.  
  187. #[inline]
  188. fn poll(mut self: Pin<&mut Self>, _waker: &Waker) -> Poll<T> {
  189. Poll::Ready(self.0.take().unwrap())
  190. }
  191. }
  192.  
  193. pub fn ready<T>(t: T) -> Ready<T> {
  194. Ready(Some(t))
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement