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
use crate::*;
/// Basic stream type. To use it you should provide getter function: 
/// ```rust
/// use streams_rs::{*,fn_stream::*};
/// let get = (|| StreamResult::Ok(1));
/// let mut stream = FnStream::new(get);
/// stream.token(0); // 1
/// stream.token(1); // 1
/// ```
pub struct FnStream<'a, T: Clone> {
    get: Box<dyn FnMut() -> StreamResult<T> + 'a>,
    pos: usize,
    cache: Vec<Option<T>>,
}

impl<'a, T: Clone> FnStream<'a, T> {
    pub fn new(get: impl FnMut() -> StreamResult<T> + 'a) -> Self {
        Self {
            get: Box::new(get),
            pos: 0,
            cache: vec![],
        }
    }
    
}
impl<'a,T: Clone> Stream<'a> for FnStream<'a,T> {
    type Item = T;
     fn token(&mut self, x: usize) -> StreamResult<T> {
        if let Some(Some(tmp)) = self.cache.get(x) {
            return StreamResult::Ok(tmp.clone());
        }
        let mut n = self.cache.len();
        let mut c = (0..x + 1).map(|_| None).collect::<Vec<_>>();
        while n <= x {
            let p =(self.get)();
            if let StreamResult::Ok(val) = p {
                c[n] = Some(val);
                n += 1;
            } else if let StreamResult::Err(StreamError::Str(_)) = p {
                return p;
            } else {
                c[n] = None;
            }
        }
        self.cache = c;
        StreamResult::Ok(self.cache[x].as_ref().unwrap().clone())
    }

    fn junk(&mut self, mut x: usize) {
        let c = self.cache.len();
        self.pos += x;
        if c >= x {
            self.cache.truncate(c - x);
        } else {
            self.cache = vec![];
            x = x - c;
            while x > 0 {
                (self.get)();
                x = x - 1;
            }
        }
    }

    fn pos(&self) -> usize {
        self.pos
    }
}