pub trait ResetIterator : Iterator {
fn offset(&self) -> usize;
fn backup(&mut self, n:usize);
fn reset(&mut self);
}
use std::str::Chars;
pub struct ResetChars<'a> {
iter: Chars<'a>,
items: Vec<char>,
start: usize,
offset: usize,
byte_offset: usize
}
impl<'a> ResetChars<'a> {
pub fn new(iter:Chars<'a>) -> Self {
Self{iter, items: Vec::new(), start:0, offset:0, byte_offset:0 }
}
pub fn offset(&self) -> usize {
self.offset
}
pub fn byte_offset(&self) -> usize {
self.byte_offset
}
pub fn backup(&mut self, n:usize) {
assert!(n <= self.items.len());
self.offset = self.offset - n;
let m = self.items.len() - n;
for i in m .. self.items.len() {
self.byte_offset -= self.items[i].len_utf8();
}
}
pub fn reset(&mut self) {
let n = self.offset - self.start;
self.start = self.offset;
self.items.drain(0..n);
}
}
impl<'a> Iterator for ResetChars<'a> {
type Item = char;
fn next(&mut self) -> Option<char> {
let i = self.offset - self.start;
if i >= self.items.len() {
match self.iter.next() {
Some(v) => {self.items.push(v);}
None => {return None;}
};
}
let c = self.items[i];
self.offset += 1;
self.byte_offset += c.len_utf8();
Some(c)
}
}
impl<'a> ResetIterator for ResetChars<'a> {
fn offset(&self) -> usize {
self.offset()
}
fn backup(&mut self, n:usize) {
self.backup(n)
}
fn reset(&mut self) {
self.reset()
}
}