geoarrow2/array/linestring/
iterator.rsuse crate::array::LineStringArray;
use crate::scalar::LineString;
use crate::trait_::GeoArrayAccessor;
use crate::GeometryArrayTrait;
use arrow_array::OffsetSizeTrait;
use arrow_buffer::NullBuffer;
#[derive(Clone, Debug)]
pub struct LineStringArrayIter<'a, O: OffsetSizeTrait> {
array: &'a LineStringArray<O>,
logical_nulls: Option<NullBuffer>,
current: usize,
current_end: usize,
}
impl<'a, O: OffsetSizeTrait> LineStringArrayIter<'a, O> {
#[inline]
pub fn new(array: &'a LineStringArray<O>) -> Self {
let len = array.len();
let logical_nulls = array.logical_nulls();
Self {
array,
logical_nulls,
current: 0,
current_end: len,
}
}
#[inline]
fn is_null(&self, idx: usize) -> bool {
self.logical_nulls
.as_ref()
.map(|x| x.is_null(idx))
.unwrap_or_default()
}
}
impl<'a, O: OffsetSizeTrait> Iterator for LineStringArrayIter<'a, O> {
type Item = Option<LineString<'a, O>>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.current == self.current_end {
None
} else if self.is_null(self.current) {
self.current += 1;
Some(None)
} else {
let old = self.current;
self.current += 1;
unsafe { Some(Some(self.array.value_unchecked(old))) }
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(
self.array.len() - self.current,
Some(self.array.len() - self.current),
)
}
}
impl<'a, O: OffsetSizeTrait> DoubleEndedIterator for LineStringArrayIter<'a, O> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.current_end == self.current {
None
} else {
self.current_end -= 1;
Some(if self.is_null(self.current_end) {
None
} else {
unsafe { Some(self.array.value_unchecked(self.current_end)) }
})
}
}
}
impl<'a, O: OffsetSizeTrait> ExactSizeIterator for LineStringArrayIter<'a, O> {}
impl<'a, O: OffsetSizeTrait> LineStringArray<O> {
pub fn iter(&'a self) -> LineStringArrayIter<O> {
LineStringArrayIter::new(self)
}
}