use super::IndexHandler;
use std::{
ops::Index,
sync::{Arc, Mutex},
};
pub struct Diterator<T: Index<usize>>
where
T::Output: Clone + Default,
{
data: T,
handler: Arc<Mutex<IndexHandler>>,
}
impl<T: Index<usize>> Diterator<T>
where
T::Output: Clone + Default,
{
pub fn new(data: T) -> (Self, Arc<Mutex<IndexHandler>>) {
let handler = Arc::new(Mutex::new(IndexHandler::new(None, None)));
let handler_ = handler.clone();
(Self { data, handler }, handler_)
}
}
impl<T: Index<usize>> Iterator for Diterator<T>
where
T::Output: Clone + Default,
{
type Item = T::Output;
fn next(&mut self) -> Option<Self::Item> {
if let Some(index) = self.handler.lock().unwrap().next_index() {
return Some(self.data[index].clone());
}
Some(T::Output::default())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_diterator() {
let data = vec![1, 2, 3, 4, 5];
let (mut diter, handler) = Diterator::new(data);
handler.lock().unwrap().set_range(1..4);
assert_eq!(diter.next(), Some(2));
assert_eq!(diter.next(), Some(3));
assert_eq!(diter.next(), Some(4));
assert_eq!(diter.next(), Some(0));
assert_eq!(diter.next(), Some(0));
handler.lock().unwrap().set_range(0..5);
assert_eq!(diter.next(), Some(1));
assert_eq!(diter.next(), Some(2));
assert_eq!(diter.next(), Some(3));
assert_eq!(diter.next(), Some(4));
assert_eq!(diter.next(), Some(5));
assert_eq!(diter.next(), Some(0));
assert_eq!(diter.next(), Some(0));
}
#[test]
fn test_diterator_map() {
let data = vec![1, 2, 3, 4, 5];
let (diter, handler) = Diterator::new(data);
let mut iter = diter.map(|x| x * 2);
handler.lock().unwrap().set_range(1..4);
assert_eq!(iter.next(), Some(4));
assert_eq!(iter.next(), Some(6));
handler.lock().unwrap().set_range(0..5);
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(4));
handler.lock().unwrap().clear_range();
handler.lock().unwrap().set_next_range(1..4);
assert_eq!(iter.next(), Some(4));
}
}