use super::BacktrackingRecorder;
use super::BacktrackingState::*;
pub struct CopyingBacktrackingIterator<'record, I> where I: Iterator, I::Item: Clone {
recorder: &'record mut BacktrackingRecorder<I>,
}
impl<'record, I> Iterator for CopyingBacktrackingIterator<'record, I> where I: Iterator, I::Item: Clone {
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
use crate::{Backtracking, Progressing};
match self.recorder.state {
Progressing => {
if let Some(val) = self.recorder.iterator.next() {
self.recorder.backtracking_vec.push(val.clone());
Some(val)
} else {
None
}
},
Backtracking { position } => {
if position >= self.recorder.backtracking_vec.len() {
self.recorder.state = Progressing;
self.next()
} else {
let backtracked_value = self.recorder.backtracking_vec[position].clone();
let new_position = position + 1;
self.recorder.state = Backtracking { position: new_position };
Some(backtracked_value)
}
},
}
}
}
impl<'record, I> CopyingBacktrackingIterator<'record, I> where I:Iterator, I::Item: Clone {
pub(crate) fn new(recorder: &'record mut BacktrackingRecorder<I>) -> Self {
CopyingBacktrackingIterator {
recorder,
}
}
}
use super::BacktrackingIterator;
impl<'record, I> BacktrackingIterator for CopyingBacktrackingIterator<'record, I> where I:Iterator, I::Item: Clone {
type RefPoint = usize;
fn get_ref_point(&self) -> usize {
match self.recorder.state {
Progressing => self.recorder.backtracking_vec.len(),
Backtracking { position } => position,
}
}
fn get_oldest_point(&self) -> usize {
0_usize
}
fn backtrack(&mut self, position: usize) {
self.recorder.state = Backtracking { position };
}
}
use super::Walkbackable;
impl<'history, 'record, I: 'history> Walkbackable<'history> for CopyingBacktrackingIterator<'record, I>
where I: Iterator, I::Item: Clone, 'history : 'record {
type RefPoint = usize;
type Item = I::Item;
type Walkback = CopyingWalkback<'history, I>;
fn walk_back(&'history self) -> CopyingWalkback<'history, I> {
CopyingWalkback::new(self)
}
}
pub struct CopyingWalkback<'record, I> where I: Iterator, I::Item: Clone {
backtracker: &'record BacktrackingRecorder<I>,
reverse_position: usize,
}
impl<'history, I> CopyingWalkback<'history, I> where I: Iterator, I::Item: Clone {
fn new(backtracker: &'history CopyingBacktrackingIterator<I>) -> Self {
let history_len = backtracker.recorder.backtracking_vec.len();
CopyingWalkback {
backtracker: &backtracker.recorder,
reverse_position: history_len,
}
}
}
use super::Walkback;
impl<'history, I> Walkback<'history> for CopyingWalkback<'history, I> where I: Iterator, I::Item: Clone {
type RefPoint = usize;
fn get_ref_point(&self) -> usize {
self.reverse_position
}
}
impl<'history, I> Iterator for CopyingWalkback<'history, I> where I: Iterator, I::Item: Clone {
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
if self.reverse_position == 0 {
None
} else {
let new_position = self.reverse_position - 1_usize;
let val = &self.backtracker.backtracking_vec[new_position];
self.reverse_position = new_position;
Some(val.clone())
}
}
}