Guest User

Untitled

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