geoarrow2/array/multipoint/
iterator.rsuse crate::array::MultiPointArray;
use crate::scalar::MultiPoint;
use crate::trait_::GeoArrayAccessor;
use crate::GeometryArrayTrait;
use arrow_array::OffsetSizeTrait;
use arrow_buffer::NullBuffer;
#[derive(Clone, Debug)]
pub struct MultiPointArrayIter<'a, O: OffsetSizeTrait> {
array: &'a MultiPointArray<O>,
logical_nulls: Option<NullBuffer>,
current: usize,
current_end: usize,
}
impl<'a, O: OffsetSizeTrait> MultiPointArrayIter<'a, O> {
#[inline]
pub fn new(array: &'a MultiPointArray<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 MultiPointArrayIter<'a, O> {
type Item = Option<MultiPoint<'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 MultiPointArrayIter<'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 MultiPointArrayIter<'a, O> {}
impl<'a, O: OffsetSizeTrait> MultiPointArray<O> {
pub fn iter(&'a self) -> MultiPointArrayIter<O> {
MultiPointArrayIter::new(self)
}
}