1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
// use std::mem::replace;
// use super::*;
pub trait FlatScan {
type YieldInput;
type ReturnInput;
type YieldOutputIterator: Iterator;
type ReturnOutput;
fn map_yield(&mut self, yield_input: Self::YieldInput) -> Self::YieldOutputIterator;
fn map_return(&mut self, return_input: Self::ReturnInput) -> Self::ReturnOutput;
}
/*
pub trait FlatScan {
type YieldInput;
type ReturnInput;
type OutputGenerator: Generator;
fn map_yield(
self,
prior: Option<<Self::OutputGenerator as Generator>::Return>,
input: Self::YieldInput,
) -> Self::OutputGenerator;
fn map_return(
self,
prior: Option<<Self::OutputGenerator as Generator>::Return>,
input: Self::ReturnInput,
) -> Self::OutputGenerator;
}
//
pub struct FlatScanGenerator<I, F: FlatScan> {
input: I,
flat_scan: F,
ret: Option<<F::OutputGenerator as Generator>::Return>,
list: Option<F::OutputGenerator>,
}
impl<I: Generator, F: FlatScan<Input = I::Yield> + Copy> Generator for FlatScanGenerator<I, F> {
type Yield = <F::OutputGenerator as Generator>::Yield;
type Return = (Option<<F::OutputGenerator as Generator>::Return>, I::Return);
fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> {
loop {
match &mut self.list {
Some(list) => match list.resume() {
GeneratorState::Yielded(y) => return GeneratorState::Yielded(y),
GeneratorState::Completed(c) => {
self.list = None;
self.ret = Some(c);
}
},
None => {
let ret = replace(&mut self.ret, None);
match self.input.resume() {
GeneratorState::Yielded(y) => self.list = Some(self.flat_scan.map_input(ret, y)),
GeneratorState::Completed(c) => return GeneratorState::Completed((ret, c)),
}
}
}
}
}
}
pub trait FlatScanSugar: Generator + Sized {
fn flat_scan<F: FlatScan<Input = Self::Yield>>(
self,
flat_scan: F,
ret: Option<<F::OutputGenerator as Generator>::Return>,
) -> FlatScanGenerator<Self, F>;
}
impl<G: Generator> FlatScanSugar for G {
fn flat_scan<F: FlatScan<Input = Self::Yield>>(
self,
flat_scan: F,
ret: Option<<F::OutputGenerator as Generator>::Return>,
) -> FlatScanGenerator<Self, F> {
FlatScanGenerator {
input: self,
flat_scan,
ret,
list: None,
}
}
}
*/