Guest User

Untitled

a guest
Jun 24th, 2018
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.46 KB | None | 0 0
  1. #![feature(pin, arbitrary_self_types, futures_api, async_await, await_macro)]
  2.  
  3. use std::future::Future;
  4. use std::marker::{PhantomData, Unpin};
  5. use std::mem::PinMut;
  6. use std::task::{Context, Poll};
  7.  
  8. fn main() {
  9.  
  10. }
  11.  
  12. pub async fn sequential_or(fut1: impl Future<Output = bool>, fut2: impl Future<Output = bool>) -> bool {
  13. await!(fut1) || await!(fut2)
  14. }
  15.  
  16. pub async fn parallel_or(fut1: impl Future<Output = bool>, fut2: impl Future<Output = bool>) -> bool {
  17. let fut1 = map_fut(fut1, |b| if b {
  18. Ok(())
  19. } else {
  20. Err(())
  21. });
  22. let fut2 = map_fut(fut2, |b| if b {
  23. Ok(())
  24. } else {
  25. Err(())
  26. });
  27. await!(parallel_or_else(fut1, fut2)).is_ok()
  28. }
  29.  
  30. pub async fn ident_fut<T>(x: T) -> T {
  31. x
  32. }
  33.  
  34. pub async fn map_fut<T, U>(fut: impl Future<Output = T>, f: impl FnOnce(T) -> U) -> U {
  35. f(await!(fut))
  36. }
  37.  
  38. #[derive(Debug, Clone)]
  39. pub struct Forever<T>(PhantomData<T>);
  40.  
  41. pub fn forever<T>() -> Forever<T> {
  42. Forever(PhantomData)
  43. }
  44.  
  45. impl<T> Future for Forever<T> {
  46. type Output = T;
  47. fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
  48. cx.local_waker().wake();
  49. Poll::Pending
  50. }
  51. }
  52.  
  53. #[derive(Debug, Clone)]
  54. pub struct WaitN<F: Future> {
  55. count: usize, // unpinned
  56. fut: F, // pinned
  57. }
  58.  
  59. pub fn wait_n<F: Future>(count: usize, fut: F) -> WaitN<F> {
  60. WaitN {
  61. count,
  62. fut,
  63. }
  64. }
  65.  
  66. impl<F: Future> WaitN<F> {
  67. fn count_mut<'a>(self: PinMut<'a, Self>) -> &'a mut usize {
  68. unsafe { &mut PinMut::get_mut(self).count }
  69. }
  70. fn fut_pinmut<'a>(self: PinMut<'a, Self>) -> PinMut<'a, F> {
  71. unsafe { PinMut::map(self, |this| &mut this.fut) }
  72. }
  73. }
  74.  
  75. impl<F: Future> Future for WaitN<F> {
  76. type Output = F::Output;
  77. fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
  78. if self.count <= 0 {
  79. self.reborrow().fut_pinmut().poll(cx)
  80. } else {
  81. *self.count_mut() -= 1;
  82. cx.local_waker().wake();
  83. Poll::Pending
  84. }
  85. }
  86. }
  87.  
  88. #[derive(Debug, Clone)]
  89. pub struct ParallelOrElse<T, E1, E2, F1, F2>
  90. where
  91. F1: Future<Output = Result<T, E1>>,
  92. F2: Future<Output = Result<T, E2>>,
  93. {
  94. fut1: F1, // pinned
  95. fut2: F2, // pinned
  96. error1: Option<E1>, // unpinned
  97. error2: Option<E2>, // unpinned
  98. }
  99.  
  100. pub fn parallel_or_else<T, E1, E2, F1, F2>(fut1: F1, fut2: F2) -> ParallelOrElse<T, E1, E2, F1, F2>
  101. where
  102. F1: Future<Output = Result<T, E1>>,
  103. F2: Future<Output = Result<T, E2>>,
  104. {
  105. ParallelOrElse {
  106. fut1,
  107. fut2,
  108. error1: None,
  109. error2: None,
  110. }
  111. }
  112.  
  113. impl<T, E1, E2, F1, F2> ParallelOrElse<T, E1, E2, F1, F2>
  114. where
  115. F1: Future<Output = Result<T, E1>>,
  116. F2: Future<Output = Result<T, E2>>,
  117. {
  118. fn fut1_pinmut<'a>(self: PinMut<'a, Self>) -> PinMut<'a, F1> {
  119. unsafe { PinMut::map(self, |this| &mut this.fut1) }
  120. }
  121. fn fut2_pinmut<'a>(self: PinMut<'a, Self>) -> PinMut<'a, F2> {
  122. unsafe { PinMut::map(self, |this| &mut this.fut2) }
  123. }
  124. fn error1_mut<'a>(self: PinMut<'a, Self>) -> &'a mut Option<E1> {
  125. unsafe { &mut PinMut::get_mut(self).error1 }
  126. }
  127. fn error2_mut<'a>(self: PinMut<'a, Self>) -> &'a mut Option<E2> {
  128. unsafe { &mut PinMut::get_mut(self).error2 }
  129. }
  130. }
  131.  
  132. impl<T, E1, E2, F1, F2> Future for ParallelOrElse<T, E1, E2, F1, F2>
  133. where
  134. F1: Future<Output = Result<T, E1>>,
  135. F2: Future<Output = Result<T, E2>>,
  136. {
  137. type Output = Result<T, (E1, E2)>;
  138. fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
  139. if self.error1.is_none() {
  140. *self.reborrow().error1_mut() = match self.reborrow().fut1_pinmut().poll(cx) {
  141. Poll::Ready(Ok(x)) => return Poll::Ready(Ok(x)),
  142. Poll::Ready(Err(e)) => Some(e),
  143. Poll::Pending => None,
  144. };
  145. }
  146. if self.error2.is_none() {
  147. *self.reborrow().error2_mut() = match self.reborrow().fut2_pinmut().poll(cx) {
  148. Poll::Ready(Ok(x)) => return Poll::Ready(Ok(x)),
  149. Poll::Ready(Err(e)) => Some(e),
  150. Poll::Pending => None,
  151. };
  152. }
  153. if self.error1.is_some() && self.error2.is_some() {
  154. return Poll::Ready(Err((self.reborrow().error1_mut().take().unwrap(), self.reborrow().error2_mut().take().unwrap())));
  155. }
  156. Poll::Pending
  157. }
  158. }
  159.  
  160. impl<T, E1, E2, F1, F2> Unpin for ParallelOrElse<T, E1, E2, F1, F2>
  161. where
  162. F1: Future<Output = Result<T, E1>> + Unpin,
  163. F2: Future<Output = Result<T, E2>> + Unpin,
  164. {}
Add Comment
Please, Sign In to add comment