Guest User

Untitled

a guest
May 20th, 2018
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.75 KB | None | 0 0
  1. #![feature(generator_trait, generators)]
  2.  
  3. use std::ops::Generator;
  4. use std::ops::GeneratorState;
  5.  
  6. fn test_select() {
  7. let gen = || {
  8. yield;
  9. yield;
  10. return 1;
  11. };
  12.  
  13. let mut select = gen
  14. .into_stepfn()
  15. .map(|n| n * 10)
  16. .select(Callable::new(|| {
  17. yield;
  18. return "Foo";
  19. }));
  20.  
  21. assert!(select.resume().unwrap().is_yield() == true);
  22.  
  23. let (ret, mut remaining_callable) = match select.resume() {
  24. Some(State::Return(Either::Right(result))) => result,
  25. _ => panic!()
  26. };
  27.  
  28. assert_eq!(ret, "Foo");
  29. assert_eq!(select.resume().is_none(), true);
  30.  
  31. //select called the first generator twice, a next call results in a return!
  32. assert_eq!(remaining_callable.resume(), Some(State::Return(10)));
  33.  
  34. }
  35.  
  36. fn main() {
  37. test_select()
  38. }
  39.  
  40. macro_rules! return_from_yield {
  41. ($g:expr) => {
  42. unsafe {
  43. match $g.resume() {
  44. GeneratorState::Yielded(_) => return Some(State::Yield),
  45. GeneratorState::Complete(ret) => ret,
  46. }
  47. }
  48. }
  49. }
  50.  
  51. #[macro_export]
  52. macro_rules! resume_from {
  53. ($s:expr) => {
  54. match $s.resume() {
  55. Some(State::Return(ret)) => ret,
  56. Some(State::Yield) => return Some(State::Yield),
  57. None => return None
  58. }
  59. }
  60. }
  61.  
  62. #[derive(PartialEq, Eq, Ord, PartialOrd, Debug, Hash)]
  63. pub enum State<T> {
  64. Yield,
  65. Return(T),
  66. }
  67.  
  68. impl <T> State<T> {
  69. pub fn is_yield(&self) -> bool {
  70. match self {
  71. &State::Yield => true,
  72. _ => false,
  73. }
  74. }
  75.  
  76. pub fn is_return(&self) -> bool {
  77. !self.is_yield()
  78. }
  79.  
  80. pub fn take(self) -> Option<T> {
  81. match self {
  82. State::Return(value) => Some(value),
  83. _ => None
  84. }
  85. }
  86. }
  87.  
  88. pub type Resume<T> = Option<State<T>>;
  89.  
  90. pub trait StepFn {
  91. type Return;
  92.  
  93. fn resume(&mut self) -> Resume<Self::Return>;
  94.  
  95. fn map<F, R>(self, f: F) -> Map<Self, F>
  96. where
  97. Self: Sized,
  98. F: FnMut(Self::Return) -> R,
  99. {
  100. Map::new(self, f)
  101. }
  102.  
  103. fn filter<F>(self, predicate: F) -> Filter<Self, F>
  104. where
  105. Self:Sized,
  106. F: Fn(&Self::Return) -> bool
  107. {
  108. Filter::new(self, predicate)
  109. }
  110.  
  111. fn select<S: StepFn>(self, other: S) -> Select<Self, S>
  112. where
  113. Self: Sized
  114. {
  115. Select::new(self, other)
  116. }
  117. }
  118.  
  119. pub trait IntoStepFn {
  120. type StepFn: StepFn;
  121.  
  122. fn into_stepfn(self) -> Self::StepFn;
  123. }
  124.  
  125. impl <G> IntoStepFn for G
  126. where
  127. G: Generator
  128. {
  129. type StepFn = Callable<G>;
  130.  
  131. fn into_stepfn(self) -> Self::StepFn {
  132. Callable::new(self)
  133. }
  134. }
  135. //we are responsible, as soon as we hit a return from the generator, we call .take()
  136. //on the option, so we never call resume() again.
  137. pub struct Callable<G>(Option<G>);
  138.  
  139. impl <G> Callable<G> {
  140. pub fn new(generator: G) -> Self {
  141. Callable(Some(generator))
  142. }
  143. }
  144.  
  145. impl <G> StepFn for Callable<G>
  146. where
  147. G: Generator
  148. {
  149. type Return = G::Return;
  150.  
  151. fn resume(&mut self) -> Resume<Self::Return> {
  152.  
  153. let ret = return_from_yield!(self.0.as_mut()?);
  154. self.0.take();
  155. Some(State::Return(ret))
  156. }
  157. }
  158.  
  159. pub struct Map<S, F> {
  160. resume: S,
  161. func: F,
  162. }
  163.  
  164. impl <S, F> Map<S, F> {
  165.  
  166. #[inline]
  167. fn new(resume: S, func: F) -> Self {
  168. Map { resume, func }
  169. }
  170. }
  171.  
  172. impl <S, F, R> StepFn for Map<S, F>
  173. where
  174. S: StepFn,
  175. F: FnMut(S::Return) -> R,
  176. {
  177. type Return = R;
  178.  
  179. #[inline]
  180. fn resume(&mut self) -> Resume<Self::Return> {
  181. let r = resume_from!(self.resume);
  182.  
  183. Some(State::Return((self.func)(r)))
  184. }
  185. }
  186.  
  187. pub struct Filter<S, F> {
  188. resume: S,
  189. predicate: F,
  190. }
  191.  
  192. impl <S, F> Filter<S, F> {
  193. #[inline]
  194. fn new(resume: S, predicate: F) -> Self {
  195. Filter { resume, predicate }
  196. }
  197. }
  198.  
  199. impl <S, F> StepFn for Filter<S, F>
  200. where
  201. S: StepFn,
  202. F: Fn(&S::Return) -> bool
  203. {
  204. type Return = S::Return;
  205.  
  206. fn resume(&mut self) -> Resume<Self::Return> {
  207. let r = resume_from!(self.resume);
  208.  
  209. if (self.predicate)(&r) {
  210. return Some(State::Return(r))
  211. }
  212. None
  213. }
  214. }
  215.  
  216. #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
  217. pub enum Either<L, R> {
  218. Left(L),
  219. Right(R),
  220. }
  221.  
  222. impl <L, R> Either <L, R> {
  223. pub fn is_right(&self) -> bool {
  224. match self {
  225. Either::Right(_) => true,
  226. _ => false,
  227. }
  228. }
  229.  
  230. pub fn is_left(&self) -> bool {
  231. !self.is_right()
  232. }
  233.  
  234. pub fn into_left(self) -> Option<L> {
  235. match self {
  236. Either::Left(value) => Some(value),
  237. _ => None,
  238. }
  239. }
  240.  
  241. pub fn into_right(self) -> Option<R> {
  242. match self {
  243. Either::Right(value) => Some(value),
  244. _ => None,
  245. }
  246. }
  247. }
  248. #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
  249. pub struct Select<A, B> {
  250. inner: Option<(A, B)>
  251. }
  252.  
  253. impl <A, B> Select<A, B> {
  254. fn new(a: A, b: B) -> Self {
  255. Select { inner: Some((a, b)) }
  256. }
  257. }
  258.  
  259. impl <A: StepFn, B: StepFn> StepFn for Select<A, B>
  260. {
  261. type Return = Either<(A::Return, B), (B::Return, A)>;
  262.  
  263. fn resume(&mut self) -> Resume<Self::Return> {
  264. let (mut a, mut b) = self.inner.take()?;
  265. match a.resume() {
  266. Some(State::Return(ret)) => Some(State::Return(Either::Left((ret, b)))),
  267. | Some(State::Yield)
  268. | None => {
  269. match b.resume() {
  270. Some(State::Return(ret)) => Some(State::Return(Either::Right((ret, a)))),
  271. None => None,
  272. Some(State::Yield) => {
  273. self.inner = Some((a, b));
  274. Some(State::Yield)
  275. }
  276. }
  277. }
  278. }
  279. }
  280. }
Add Comment
Please, Sign In to add comment