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
use std::io::{BufRead,Read}; use crate::*; use std::borrow::Cow; use std::io::ErrorKind; pub struct LineReadStream<'a,T: BufRead> { pub value: &'a mut T, pub cache: Vec<Option<String>>, } impl<'a,T: BufRead> LineReadStream<'a,T> { pub fn new(item: &'a mut T) -> Self { Self { value: item, cache: vec![] } } } impl<'b,'a: 'b,T: BufRead> Stream<'a> for LineReadStream<'a,T> { type Item = Option<String>; fn token(&mut self,x: usize) -> StreamResult<Option<String>> { if self.cache.get(x).is_some() { return match &self.cache[x] { Some(x) => StreamResult::Ok(Some(x.clone())), _ => StreamResult::Ok(None) } } let mut n = self.cache.len(); let mut c = (0..x + 1).map(|_| None).collect::<Vec<_>>(); while n <= x { let mut buf = String::new(); let p = self.value.read_line(&mut buf); match p { Ok(0) => { c[n] = None; } Ok(_) => { c[n] = Some(buf); n += 1; } Err(e) => return StreamResult::Err(StreamError::Str(e.to_string())), } } self.cache = c; StreamResult::Ok(self.cache[x].clone()) } fn junk(&mut self,mut x: usize) { let c = self.cache.len(); if c >= x { self.cache.truncate(c - x); } else { self.cache = vec![]; x = x - c; while x > 0 { let _ = self.value.read_line(&mut String::new()); x = x - 1; } } } fn pos(&self) -> usize { 0 } }