use std::ops::Range;
use crate::usage_types::coordinates::Coordinate;
use crate::VectorGrid;
pub struct IterVectorGridChunk<'a, ItemType> {
source: &'a VectorGrid<ItemType>,
ended: bool,
location: Coordinate,
shape: Vec<Range<usize>>
}
impl<ItemType> IterVectorGridChunk<'_, ItemType> {
fn increment_position(&mut self, i: usize) {
if i >= self.shape.len() {
self.ended = true;
return;
}
*self.location.index_mut(i) += 1;
if *self.location.index_mut(i) >= self.shape[i].end as isize {
*self.location.index_mut(i) = self.shape[i].start as isize;
self.increment_position(i + 1);
}
}
}
impl<'a, ItemType> Iterator for IterVectorGridChunk<'a, ItemType> {
type Item = &'a ItemType;
fn next(&mut self) -> Option<Self::Item> {
if self.ended {
return None;
}
let result = Some(&self.source[&self.location]);
self.increment_position(0);
result
}
}
impl<ItemType> VectorGrid<ItemType> {
pub fn iter_chunk<'a>(&'a self, shape: Vec<Range<usize>>) -> IterVectorGridChunk<'a, ItemType> {
IterVectorGridChunk { source: self, ended: false, location: shape.iter().map(|size| {size.start as isize}).collect(), shape }
}
}