1pub trait Reader<T>: Iterator {
3 fn len(&self) -> usize;
5 fn pos(&self) -> usize;
7 fn rollback(&mut self, amount: usize) -> Result<(), ()>;
9
10 fn is_end(&self) -> bool {
12 self.len() == 0 || self.len() <= self.pos()
13 }
14
15 fn try_read(&mut self, amount: usize) -> Option<T>;
17}
18
19pub struct TextReader {
21 pos: usize,
22 text: Vec<char>,
23}
24
25impl Iterator for TextReader {
26 type Item = char;
27
28 fn next(&mut self) -> Option<Self::Item> {
30 let current = self.text.get(self.pos).copied();
31
32 self.pos += 1;
33
34 current
35 }
36}
37
38impl Reader<String> for TextReader {
39 fn len(&self) -> usize {
40 self.text.len()
41 }
42
43 fn pos(&self) -> usize {
44 self.pos
45 }
46
47 fn rollback(&mut self, amount: usize) -> Result<(), ()> {
48 if self.pos < amount {
49 return Err(());
50 }
51
52 self.pos -= amount;
53
54 Ok(())
55 }
56
57 fn try_read(&mut self, amount: usize) -> Option<String> {
58 let mut s = String::with_capacity(amount);
59
60 let mut left = amount;
61 while left > 0 {
62 if self.is_end() {
63 self.pos -= amount - left;
64
65 return None;
66 }
67
68 let ch = self.next().unwrap();
69 s.push(ch);
70
71 left -= 1;
72 }
73
74 Some(s)
75 }
76}
77
78impl TextReader {
79 pub fn new() -> Self {
81 TextReader { pos: 0, text: vec![] }
82 }
83
84 pub fn from_text(s: &str) -> Self {
88 TextReader { pos: 0, text: s.chars().collect() }
89 }
90
91 pub fn read_until_char(&mut self, ch: char) -> Option<String> {
95 let mut s = String::new();
96
97 while self.is_end() == false {
98 let read_ch = self.next().unwrap();
99 s.push(read_ch);
100
101 if read_ch == ch {
102 return Some(s);
103 }
104 }
105
106 self.rollback(s.len()).unwrap();
107 None
108 }
109}