1use std::fmt;
20use std::iter::FusedIterator;
21use std::ops::Range;
22
23use geo_types::Geometry;
24use usize_cast::IntoUsize as _;
25
26use crate::decoder::{Layer01, ParsedLayer01, ParsedProperty, ParsedScalar, Property, RawProperty};
27use crate::{Lazy, LazyParsed, MltResult, Parsed};
28
29pub trait LendingIterator {
44 type Item<'this>
46 where
47 Self: 'this;
48
49 fn next(&mut self) -> Option<Self::Item<'_>>;
51}
52
53impl<'a> Layer01<'a, Lazy> {
54 pub fn iterate_prop_names(&self) -> PropNamesIter<'_, Property<'a, Lazy>> {
62 PropNamesIter::new(&self.properties)
63 }
64}
65
66impl<'a> ParsedLayer01<'a> {
67 #[must_use]
86 pub fn iter_features(&self) -> Layer01FeatureIter<'_, 'a> {
87 Layer01FeatureIter::new(self)
88 }
89
90 pub fn iterate_prop_names(&self) -> PropNamesIter<'_, ParsedProperty<'a>> {
93 PropNamesIter::new(&self.properties)
94 }
95}
96
97#[derive(Debug, Clone, Copy)] pub struct PropName<'a>(&'a str, &'a str);
108
109impl fmt::Display for PropName<'_> {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 f.write_str(self.0)?;
112 f.write_str(self.1)
113 }
114}
115
116impl PartialEq<PropName<'_>> for PropName<'_> {
117 fn eq(&self, other: &PropName<'_>) -> bool {
118 let (a0, a1) = (self.0.as_bytes(), self.1.as_bytes());
120 let a = a0.iter().chain(a1);
121 let (b0, b1) = (other.0.as_bytes(), other.1.as_bytes());
122 let b = b0.iter().chain(b1);
123 let combined_len_eq = a0.len() + a1.len() == b0.len() + b1.len();
124 combined_len_eq && a.eq(b)
125 }
126}
127
128impl PartialEq<str> for PropName<'_> {
129 fn eq(&self, other: &str) -> bool {
131 other.strip_prefix(self.0) == Some(self.1)
132 }
133}
134
135impl PartialEq<PropName<'_>> for str {
136 fn eq(&self, other: &PropName<'_>) -> bool {
137 other == self
138 }
139}
140
141impl PartialEq<&str> for PropName<'_> {
142 fn eq(&self, other: &&str) -> bool {
143 self == *other
144 }
145}
146
147impl PartialEq<PropName<'_>> for &str {
148 fn eq(&self, other: &PropName<'_>) -> bool {
149 other == *self
150 }
151}
152
153#[derive(Debug, Clone, Copy, PartialEq)]
158pub enum PropValueRef<'a> {
159 Bool(bool),
160 I8(i8),
161 U8(u8),
162 I32(i32),
163 U32(u32),
164 I64(i64),
165 U64(u64),
166 F32(f32),
167 F64(f64),
168 Str(&'a str),
169}
170
171macro_rules! impl_from_for_prop_value_ref {
172 ($($ty:ty => $variant:ident),+ $(,)?) => {
173 $(impl From<$ty> for PropValueRef<'_> {
174 fn from(v: $ty) -> Self { Self::$variant(v) }
175 })+
176 };
177}
178impl_from_for_prop_value_ref!(
179 bool => Bool, i8 => I8, u8 => U8,
180 i32 => I32, u32 => U32,
181 i64 => I64, u64 => U64,
182 f32 => F32, f64 => F64,
183);
184
185#[derive(Debug, Clone, Copy, PartialEq)]
190pub struct ColumnRef<'a> {
191 name: PropName<'a>,
192 value: PropValueRef<'a>,
193}
194
195impl<'a> ColumnRef<'a> {
196 #[must_use]
197 pub fn name(&self) -> PropName<'a> {
198 self.name
199 }
200
201 #[must_use]
202 pub fn value(&self) -> PropValueRef<'a> {
203 self.value
204 }
205}
206
207#[derive(Debug)]
212pub struct FeatureRef<'feat, 'layer: 'feat> {
213 id: Option<u64>,
215 geometry: Geometry<i32>,
217 columns: &'layer [ParsedProperty<'layer>],
219 values: &'feat [Option<PropValueRef<'layer>>],
222}
223
224impl<'feat, 'layer: 'feat> FeatureRef<'feat, 'layer> {
225 #[must_use]
226 pub fn id(&self) -> Option<u64> {
227 self.id
228 }
229
230 #[must_use]
231 pub fn geometry(&self) -> &Geometry<i32> {
232 &self.geometry
233 }
234
235 #[must_use]
243 pub fn iter_all_properties(
244 &self,
245 ) -> impl ExactSizeIterator<Item = Option<PropValueRef<'layer>>>
246 + DoubleEndedIterator
247 + FusedIterator
248 + '_ {
249 self.values.iter().copied()
250 }
251
252 #[must_use]
257 pub fn iter_properties(
258 &self,
259 ) -> impl DoubleEndedIterator<Item = ColumnRef<'layer>> + FusedIterator + '_ {
260 PropNamesIter::new(self.columns)
261 .zip(self.values.iter().copied())
262 .filter_map(|(name, opt_val)| opt_val.map(|value| ColumnRef { name, value }))
263 }
264
265 #[must_use]
270 pub fn get_property(&self, name: &str) -> Option<PropValueRef<'layer>> {
271 self.iter_properties()
272 .find(|col| col.name() == name)
273 .map(|col| col.value())
274 }
275}
276
277pub trait ColNames {
284 type Name;
288
289 fn name_count(&self) -> usize;
291
292 fn name_at(&self, idx: usize) -> Self::Name;
294}
295
296impl<'p> ColNames for ParsedProperty<'p> {
297 type Name = PropName<'p>;
298
299 fn name_count(&self) -> usize {
300 match self {
301 Self::SharedDict(sd) => sd.items.len(),
302 _ => 1,
303 }
304 }
305
306 fn name_at(&self, idx: usize) -> PropName<'p> {
307 use ParsedProperty as P;
308 match self {
309 P::Bool(s) => PropName(s.name, ""),
310 P::I8(s) => PropName(s.name, ""),
311 P::U8(s) => PropName(s.name, ""),
312 P::I32(s) => PropName(s.name, ""),
313 P::U32(s) => PropName(s.name, ""),
314 P::I64(s) => PropName(s.name, ""),
315 P::U64(s) => PropName(s.name, ""),
316 P::F32(s) => PropName(s.name, ""),
317 P::F64(s) => PropName(s.name, ""),
318 P::Str(s) => PropName(s.name, ""),
319 P::SharedDict(sd) => PropName(sd.prefix, sd.items[idx].suffix),
320 }
321 }
322}
323
324impl<'p> ColNames for RawProperty<'p> {
325 type Name = PropName<'p>;
326
327 fn name_count(&self) -> usize {
328 match self {
329 Self::SharedDict(sd) => sd.children.len(),
330 _ => 1,
331 }
332 }
333
334 fn name_at(&self, idx: usize) -> PropName<'p> {
335 use RawProperty as P;
336 match self {
337 P::Bool(s)
338 | P::I8(s)
339 | P::U8(s)
340 | P::I32(s)
341 | P::U32(s)
342 | P::I64(s)
343 | P::U64(s)
344 | P::F32(s)
345 | P::F64(s) => PropName(s.name, ""),
346 P::Str(s) => PropName(s.name, ""),
347 P::SharedDict(sd) => PropName(sd.name, sd.children[idx].name),
348 }
349 }
350}
351
352impl<'p> ColNames for LazyParsed<RawProperty<'p>, ParsedProperty<'p>> {
354 type Name = PropName<'p>;
355
356 fn name_count(&self) -> usize {
357 match self {
358 Self::Raw(r) => r.name_count(),
359 Self::Parsed(p) => p.name_count(),
360 Self::ParsingFailed => 0,
361 }
362 }
363
364 fn name_at(&self, idx: usize) -> PropName<'p> {
365 match self {
366 Self::Raw(r) => r.name_at(idx),
367 Self::Parsed(p) => p.name_at(idx),
368 Self::ParsingFailed => unreachable!("ParsingFailed contributes no names"),
369 }
370 }
371}
372
373#[must_use]
378pub struct PropNamesIter<'a, C> {
379 props: &'a [C],
380 cols: Range<usize>,
383 front_sub: usize,
385 back_sub: usize,
387 remaining: usize,
390}
391
392impl<'a, C: ColNames> PropNamesIter<'a, C> {
393 pub(crate) fn new(props: &'a [C]) -> Self {
394 Self {
395 props,
396 cols: 0..props.len(),
397 front_sub: 0,
398 back_sub: props.last().map_or(0, ColNames::name_count),
399 remaining: props.iter().map(ColNames::name_count).sum(),
400 }
401 }
402}
403
404impl<C: ColNames> Iterator for PropNamesIter<'_, C> {
405 type Item = C::Name;
406
407 fn next(&mut self) -> Option<C::Name> {
408 if self.remaining == 0 {
409 return None;
410 }
411 self.remaining -= 1;
412 loop {
413 let col = &self.props[self.cols.start];
415 if self.front_sub < col.name_count() {
416 let name = col.name_at(self.front_sub);
417 self.front_sub += 1;
418 return Some(name);
419 }
420 self.cols.start += 1;
421 self.front_sub = 0;
422 }
423 }
424
425 fn size_hint(&self) -> (usize, Option<usize>) {
426 (self.remaining, Some(self.remaining))
427 }
428}
429
430impl<C: ColNames> DoubleEndedIterator for PropNamesIter<'_, C> {
431 fn next_back(&mut self) -> Option<C::Name> {
432 if self.remaining == 0 {
433 return None;
434 }
435 self.remaining -= 1;
436 loop {
437 if self.back_sub > 0 {
438 self.back_sub -= 1;
439 return Some(self.props[self.cols.end - 1].name_at(self.back_sub));
440 }
441 self.cols.end -= 1;
442 self.back_sub = self.props[self.cols.end - 1].name_count();
443 }
444 }
445}
446
447impl<C: ColNames> ExactSizeIterator for PropNamesIter<'_, C> {
448 fn len(&self) -> usize {
449 self.remaining
450 }
451}
452
453impl<C: ColNames> FusedIterator for PropNamesIter<'_, C> {}
454
455type ColValIter<'l> = Box<dyn Iterator<Item = Option<PropValueRef<'l>>> + 'l>;
457
458fn build_col_iters<'p>(columns: &'p [ParsedProperty<'p>]) -> Vec<ColValIter<'p>> {
463 use ParsedProperty as PP;
464 let mut iters: Vec<ColValIter<'p>> = Vec::new();
465 for col in columns {
466 match col {
467 PP::Bool(s) => iters.push(scalar_col_iter(s)),
468 PP::I8(s) => iters.push(scalar_col_iter(s)),
469 PP::U8(s) => iters.push(scalar_col_iter(s)),
470 PP::I32(s) => iters.push(scalar_col_iter(s)),
471 PP::U32(s) => iters.push(scalar_col_iter(s)),
472 PP::I64(s) => iters.push(scalar_col_iter(s)),
473 PP::U64(s) => iters.push(scalar_col_iter(s)),
474 PP::F32(s) => iters.push(scalar_col_iter(s)),
475 PP::F64(s) => iters.push(scalar_col_iter(s)),
476 PP::Str(strings) => {
477 let data: &'p str = strings.data.as_ref();
478 let lengths: &'p [i32] = &strings.lengths;
479 let mut curr_end: usize = 0;
480 let mut feat_idx = 0usize;
481 iters.push(Box::new(std::iter::from_fn(move || {
482 let &end_i32 = lengths.get(feat_idx)?;
483 feat_idx += 1;
484 if end_i32 >= 0 {
485 let start = curr_end;
486 curr_end = end_i32.cast_unsigned().into_usize();
487 Some(data.get(start..curr_end).map(PropValueRef::Str))
488 } else {
489 Some(None)
491 }
492 })));
493 }
494 PP::SharedDict(dict) => {
495 for item in &dict.items {
496 let dict_ref: &'p _ = dict;
497 let item_ref: &'p _ = item;
498 let mut feat_idx = 0usize;
499 iters.push(Box::new(std::iter::from_fn(move || {
500 if feat_idx >= item_ref.ranges.len() {
501 return None;
502 }
503 let idx = feat_idx;
504 feat_idx += 1;
505 Some(item_ref.get(dict_ref, idx).map(PropValueRef::Str))
506 })));
507 }
508 }
509 }
510 }
511 iters
512}
513
514fn scalar_col_iter<'p, T>(scalar: &'p ParsedScalar<'p, T>) -> ColValIter<'p>
516where
517 T: Copy + PartialEq,
518 PropValueRef<'p>: From<T>,
519{
520 Box::new(scalar.iter_optional().map(|o| o.map(PropValueRef::from)))
521}
522
523pub struct Layer01FeatureIter<'layer, 'data: 'layer> {
533 layer: &'layer Layer01<'data, Parsed>,
534 index: usize,
535 feature_count: usize,
536 id_iter: Option<crate::utils::PresenceOptIter<'layer, u64>>,
538 col_iters: Vec<ColValIter<'layer>>,
540 values_buf: Vec<Option<PropValueRef<'layer>>>,
542}
543
544impl<'layer, 'data: 'layer> Layer01FeatureIter<'layer, 'data> {
545 fn new(layer: &'layer Layer01<'data, Parsed>) -> Self {
546 let col_iters = build_col_iters(&layer.properties);
547 let cap = col_iters.len();
548 Self {
549 layer,
550 index: 0,
551 feature_count: layer.feature_count(),
552 id_iter: layer.id.as_ref().map(|id| id.iter_optional()),
553 col_iters,
554 values_buf: Vec::with_capacity(cap),
555 }
556 }
557
558 #[must_use]
560 pub fn len(&self) -> usize {
561 self.feature_count - self.index
562 }
563
564 #[must_use]
566 pub fn is_empty(&self) -> bool {
567 self.index >= self.feature_count
568 }
569}
570
571impl<'layer> LendingIterator for Layer01FeatureIter<'layer, '_> {
572 type Item<'this>
573 = MltResult<FeatureRef<'this, 'layer>>
574 where
575 Self: 'this;
576
577 fn next(&mut self) -> Option<Self::Item<'_>> {
578 let index = self.index;
579 if index >= self.feature_count {
580 return None;
581 }
582 self.index += 1;
583
584 let id = self.id_iter.as_mut().and_then(Iterator::next).flatten();
587 self.values_buf.clear();
588 self.values_buf
589 .extend(self.col_iters.iter_mut().map(|it| it.next().flatten()));
590
591 Some(
592 self.layer
593 .geometry
594 .to_geojson(index)
595 .map(|geometry| FeatureRef {
596 id,
597 geometry,
598 columns: &self.layer.properties,
599 values: &self.values_buf,
600 }),
601 )
602 }
603}
604
605#[cfg(test)]
606mod tests {
607 use geo_types::Point;
608 use serde_json::Value;
609
610 use super::*;
611 use crate::Layer;
612 use crate::decoder::GeometryValues;
613 use crate::encoder::model::StagedLayer;
614 use crate::encoder::{Codecs, Encoder, Presence, StagedId, StagedProperty, StagedSharedDict};
615 use crate::test_helpers::{assert_size_hint_exact, dec, parser};
616
617 fn layer_buf(staged: StagedLayer) -> Vec<u8> {
618 staged
619 .encode_into(Encoder::default(), &mut Codecs::default())
620 .unwrap()
621 .into_layer_bytes()
622 .unwrap()
623 }
624
625 fn three_points() -> GeometryValues {
626 let mut g = GeometryValues::default();
627 g.push_geom(&Geometry::<i32>::Point(Point::new(1, 2)));
628 g.push_geom(&Geometry::<i32>::Point(Point::new(3, 4)));
629 g.push_geom(&Geometry::<i32>::Point(Point::new(5, 6)));
630 g
631 }
632
633 fn empty_layer(name: &str) -> StagedLayer {
634 staged_layer(name, StagedId::None, GeometryValues::default(), vec![])
635 }
636
637 fn staged_layer(
638 name: &str,
639 id: StagedId,
640 geometry: GeometryValues,
641 properties: Vec<StagedProperty>,
642 ) -> StagedLayer {
643 StagedLayer::new(name, 4096, id, geometry, properties).unwrap()
644 }
645
646 #[test]
647 fn prop_name_display_concatenates_parts() {
648 assert_eq!(PropName("addr:", "city").to_string(), "addr:city");
649 assert_eq!(PropName("name", "").to_string(), "name");
650 assert_eq!(PropName("", "").to_string(), "");
651 }
652
653 #[test]
654 fn prop_name_eq_str_matches_concatenation() {
655 assert_eq!(PropName("addr:", "city"), "addr:city");
656 assert_eq!("addr:city", PropName("addr:", "city"));
657 assert_ne!(PropName("addr:", "city"), "addr:");
658 assert_ne!(PropName("addr:", "city"), "city");
659 assert_eq!(PropName("name", ""), "name");
660 }
661
662 #[test]
663 fn prop_name_structural_eq_is_part_wise() {
664 assert_eq!(PropName("a", "b"), PropName("a", "b"));
665 assert_eq!(PropName("ab", ""), PropName("a", "b"));
666 }
667
668 #[test]
669 fn prop_name_eq_prop_name_semantic_equality() {
670 assert_eq!(PropName("ab", ""), PropName("a", "b"));
671 assert_eq!(PropName("", "ab"), PropName("a", "b"));
672 assert_eq!(PropName("abc", "def"), PropName("ab", "cdef"));
673 assert_eq!(PropName("a", "bcdef"), PropName("abcde", "f"));
674
675 assert_ne!(PropName("a", "b"), PropName("a", "c"));
676 assert_ne!(PropName("a", "b"), PropName("ab", "c"));
677 assert_ne!(PropName("abc", ""), PropName("ab", ""));
678 }
679
680 #[test]
681 fn prop_value_ref_scalars_convert_to_json() {
682 assert_eq!(Value::from(PropValueRef::Bool(true)), Value::Bool(true));
683 assert_eq!(Value::from(PropValueRef::Bool(false)), Value::Bool(false));
684 assert_eq!(Value::from(PropValueRef::I8(-1)), Value::from(-1_i8));
685 assert_eq!(Value::from(PropValueRef::U8(255)), Value::from(255_u8));
686 assert_eq!(
687 Value::from(PropValueRef::I32(-1000)),
688 Value::from(-1000_i32)
689 );
690 assert_eq!(Value::from(PropValueRef::U32(1000)), Value::from(1000_u32));
691 assert_eq!(
692 Value::from(PropValueRef::I64(i64::MIN)),
693 Value::from(i64::MIN)
694 );
695 assert_eq!(
696 Value::from(PropValueRef::U64(u64::MAX)),
697 Value::from(u64::MAX)
698 );
699 assert_eq!(
700 Value::from(PropValueRef::Str("hello")),
701 Value::String("hello".into())
702 );
703 }
704
705 #[test]
706 fn prop_value_ref_float_finite_is_number() {
707 assert!(matches!(
708 Value::from(PropValueRef::F32(1.5)),
709 Value::Number(_)
710 ));
711 assert!(matches!(
712 Value::from(PropValueRef::F64(2.5)),
713 Value::Number(_)
714 ));
715 }
716
717 #[test]
718 fn prop_value_ref_float_non_finite_becomes_string_sentinel() {
719 assert_eq!(
720 Value::from(PropValueRef::F32(f32::NAN)),
721 Value::String("f32::NAN".into())
722 );
723 assert_eq!(
724 Value::from(PropValueRef::F32(f32::INFINITY)),
725 Value::String("f32::INFINITY".into())
726 );
727 assert_eq!(
728 Value::from(PropValueRef::F64(f64::NAN)),
729 Value::String("f64::NAN".into())
730 );
731 assert_eq!(
732 Value::from(PropValueRef::F64(f64::NEG_INFINITY)),
733 Value::String("f64::NEG_INFINITY".into())
734 );
735 }
736
737 #[test]
738 fn empty_layer_yields_no_features() {
739 let buf = layer_buf(empty_layer("empty"));
740 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
741 let Layer::Tag01(lazy) = layer else {
742 panic!("expected Tag01")
743 };
744 let parsed = lazy.decode_all(&mut dec()).unwrap();
745
746 let iter = parsed.iter_features();
747 assert_eq!(iter.len(), 0);
748 assert!(iter.is_empty());
749 assert_eq!(parsed.iter_features().len(), 0);
750 }
751
752 #[test]
753 fn len_decreases_with_each_next() {
754 let buf = layer_buf(staged_layer("test", StagedId::None, three_points(), vec![]));
755 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
756 let Layer::Tag01(lazy) = layer else { panic!() };
757 let parsed = lazy.decode_all(&mut dec()).unwrap();
758
759 let mut iter = parsed.iter_features();
760 assert_eq!(iter.len(), 3);
761 iter.next().unwrap().unwrap();
762 assert_eq!(iter.len(), 2);
763 iter.next().unwrap().unwrap();
764 assert_eq!(iter.len(), 1);
765 iter.next().unwrap().unwrap();
766 assert_eq!(iter.len(), 0);
767 assert!(iter.is_empty());
768 assert!(iter.next().is_none());
769 }
770
771 #[test]
772 fn feature_ids_are_preserved() {
773 let buf = layer_buf(staged_layer(
774 "test",
775 StagedId::from_optional(vec![Some(100), None, Some(200)]),
776 three_points(),
777 vec![],
778 ));
779 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
780 let Layer::Tag01(lazy) = layer else { panic!() };
781 let parsed = lazy.decode_all(&mut dec()).unwrap();
782
783 let mut ids = Vec::new();
784 let mut iter = parsed.iter_features();
785 while let Some(r) = iter.next() {
786 ids.push(r.unwrap().id);
787 }
788 assert_eq!(ids, [Some(100), None, Some(200)]);
789 }
790
791 #[test]
792 fn geometry_values_match_input() {
793 let buf = layer_buf(staged_layer("test", StagedId::None, three_points(), vec![]));
794 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
795 let Layer::Tag01(lazy) = layer else { panic!() };
796 let parsed = lazy.decode_all(&mut dec()).unwrap();
797
798 let mut geoms = Vec::new();
799 let mut iter = parsed.iter_features();
800 while let Some(r) = iter.next() {
801 geoms.push(r.unwrap().geometry);
802 }
803 assert_eq!(geoms[0], Geometry::<i32>::Point(Point::new(1, 2)));
804 assert_eq!(geoms[1], Geometry::<i32>::Point(Point::new(3, 4)));
805 assert_eq!(geoms[2], Geometry::<i32>::Point(Point::new(5, 6)));
806 }
807
808 #[test]
809 fn null_scalar_values_are_skipped() {
810 let buf = layer_buf(staged_layer(
811 "test",
812 StagedId::None,
813 three_points(),
814 vec![StagedProperty::opt_u32("n", vec![Some(1), None, Some(3)])],
815 ));
816 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
817 let Layer::Tag01(lazy) = layer else { panic!() };
818 let parsed = lazy.decode_all(&mut dec()).unwrap();
819
820 let mut iter = parsed.iter_features();
821
822 {
823 let feat = iter.next().unwrap().unwrap();
824 let cols: Vec<_> = feat.iter_properties().collect();
825 assert_eq!(cols.len(), 1);
826 assert_eq!(cols[0].name, PropName("n", ""));
827 assert_eq!(cols[0].name, "n");
828 assert_eq!(cols[0].value, PropValueRef::U32(1));
829 let all: Vec<_> = feat.iter_all_properties().collect();
830 assert_eq!(all, [Some(PropValueRef::U32(1))]);
831 }
832 {
833 let feat = iter.next().unwrap().unwrap();
834 assert!(feat.iter_properties().next().is_none());
835 let all: Vec<_> = feat.iter_all_properties().collect();
836 assert_eq!(all, [None]);
837 }
838 {
839 let feat = iter.next().unwrap().unwrap();
840 assert_eq!(feat.get_property("n"), Some(PropValueRef::U32(3)));
841 let all: Vec<_> = feat.iter_all_properties().collect();
842 assert_eq!(all, [Some(PropValueRef::U32(3))]);
843 }
844
845 let names: Vec<_> = parsed.iterate_prop_names().map(|n| n.to_string()).collect();
846 assert_eq!(names, ["n"]);
847 }
848
849 #[test]
850 fn null_string_values_are_skipped() {
851 let buf = layer_buf(staged_layer(
852 "test",
853 StagedId::None,
854 three_points(),
855 vec![StagedProperty::opt_str(
856 "label",
857 vec![Some("foo"), None, Some("bar")],
858 )],
859 ));
860 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
861 let Layer::Tag01(lazy) = layer else { panic!() };
862 let parsed = lazy.decode_all(&mut dec()).unwrap();
863
864 let mut iter = parsed.iter_features();
865 {
866 let feat = iter.next().unwrap().unwrap();
867 assert_eq!(feat.get_property("label"), Some(PropValueRef::Str("foo")));
868 }
869 {
870 let feat = iter.next().unwrap().unwrap();
871 assert_eq!(feat.get_property("label"), None);
872 }
873 {
874 let feat = iter.next().unwrap().unwrap();
875 assert_eq!(feat.get_property("label"), Some(PropValueRef::Str("bar")));
876 }
877 }
878
879 #[test]
880 fn multiple_columns_independently_nullable() {
881 let buf = layer_buf(staged_layer(
882 "test",
883 StagedId::None,
884 three_points(),
885 vec![
886 StagedProperty::opt_bool("flag", vec![Some(true), Some(false), None]),
887 StagedProperty::opt_i32("score", vec![None, Some(-5), Some(7)]),
888 ],
889 ));
890 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
891 let Layer::Tag01(lazy) = layer else { panic!() };
892 let parsed = lazy.decode_all(&mut dec()).unwrap();
893
894 let mut iter = parsed.iter_features();
895
896 {
898 let feat = iter.next().unwrap().unwrap();
899 assert_eq!(feat.iter_properties().count(), 1);
900 assert_eq!(feat.get_property("flag"), Some(PropValueRef::Bool(true)));
901 assert_eq!(feat.get_property("score"), None);
902 }
903 {
905 let feat = iter.next().unwrap().unwrap();
906 assert_eq!(feat.iter_properties().count(), 2);
907 assert_eq!(feat.get_property("flag"), Some(PropValueRef::Bool(false)));
908 assert_eq!(feat.get_property("score"), Some(PropValueRef::I32(-5)));
909 }
910 {
912 let feat = iter.next().unwrap().unwrap();
913 assert_eq!(feat.iter_properties().count(), 1);
914 assert_eq!(feat.get_property("flag"), None);
915 assert_eq!(feat.get_property("score"), Some(PropValueRef::I32(7)));
916 }
917 }
918
919 #[test]
920 fn geometry_error_does_not_misalign_ids() {
921 use crate::decoder::GeometryType;
922
923 let buf = layer_buf(staged_layer(
924 "test",
925 StagedId::from_optional(vec![Some(10), Some(20), Some(30)]),
926 three_points(),
927 vec![],
928 ));
929 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
930 let Layer::Tag01(lazy) = layer else { panic!() };
931 let mut parsed = lazy.decode_all(&mut dec()).unwrap();
932
933 parsed.geometry.vector_types[1] = GeometryType::LineString;
937
938 let mut iter = parsed.iter_features();
939
940 let feat0 = iter.next().unwrap().unwrap();
942 assert_eq!(feat0.id, Some(10));
943
944 assert!(iter.next().unwrap().is_err());
946
947 let feat2 = iter.next().unwrap().unwrap();
949 assert_eq!(
950 feat2.id,
951 Some(30),
952 "id cursor was not advanced on geometry error"
953 );
954
955 assert!(iter.next().is_none());
956 }
957
958 #[test]
959 fn get_property_absent_column_returns_none() {
960 let buf = layer_buf(staged_layer(
961 "test",
962 StagedId::None,
963 three_points(),
964 vec![StagedProperty::u32("x", vec![1, 2, 3])],
965 ));
966 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
967 let Layer::Tag01(lazy) = layer else { panic!() };
968 let parsed = lazy.decode_all(&mut dec()).unwrap();
969
970 let mut iter = parsed.iter_features();
971 let feat = iter.next().unwrap().unwrap();
972 assert_eq!(feat.get_property("no_such_column"), None);
973 }
974
975 #[test]
976 fn shared_dict_columns_are_expanded() {
977 let shared_dict = StagedSharedDict::new(
978 "addr:",
979 [
980 (
981 "city",
982 vec![Some("Paris"), Some("Rome"), None],
983 Presence::Mixed,
984 ),
985 (
986 "zip",
987 vec![Some("75001"), None, Some("00100")],
988 Presence::Mixed,
989 ),
990 ],
991 )
992 .unwrap();
993
994 let buf = layer_buf(staged_layer(
995 "test",
996 StagedId::None,
997 three_points(),
998 vec![StagedProperty::SharedDict(shared_dict)],
999 ));
1000 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1001 let Layer::Tag01(lazy) = layer else { panic!() };
1002 let parsed = lazy.decode_all(&mut dec()).unwrap();
1003
1004 let mut iter = parsed.iter_features();
1005
1006 {
1008 let feat = iter.next().unwrap().unwrap();
1009 assert_eq!(
1010 feat.get_property("addr:city"),
1011 Some(PropValueRef::Str("Paris"))
1012 );
1013 assert_eq!(
1014 feat.get_property("addr:zip"),
1015 Some(PropValueRef::Str("75001"))
1016 );
1017 assert_eq!(feat.iter_properties().count(), 2);
1018 }
1019 {
1021 let feat = iter.next().unwrap().unwrap();
1022 assert_eq!(
1023 feat.get_property("addr:city"),
1024 Some(PropValueRef::Str("Rome"))
1025 );
1026 assert_eq!(feat.get_property("addr:zip"), None);
1027 assert_eq!(feat.iter_properties().count(), 1);
1028 let all: Vec<_> = feat.iter_all_properties().collect();
1030 assert_eq!(all, [Some(PropValueRef::Str("Rome")), None]);
1031 }
1032 {
1034 let feat = iter.next().unwrap().unwrap();
1035 assert_eq!(feat.get_property("addr:city"), None);
1036 assert_eq!(
1037 feat.get_property("addr:zip"),
1038 Some(PropValueRef::Str("00100"))
1039 );
1040 }
1041
1042 let names: Vec<_> = parsed.iterate_prop_names().map(|n| n.to_string()).collect();
1043 assert_eq!(names, ["addr:city", "addr:zip"]);
1044 }
1045
1046 fn strs<'p>(iter: impl Iterator<Item = PropName<'p>>) -> Vec<String> {
1047 iter.map(|n| n.to_string()).collect()
1048 }
1049
1050 fn reversed<'p>(iter: impl DoubleEndedIterator<Item = PropName<'p>>) -> Vec<String> {
1051 let mut names = strs(iter.rev());
1052 names.reverse();
1053 names
1054 }
1055
1056 fn both_ends_layer() -> Vec<u8> {
1057 let shared_dict = StagedSharedDict::new(
1058 "addr:",
1059 [
1060 ("city", vec![Some("Paris"); 3], Presence::AllPresent),
1061 ("zip", vec![Some("75001"); 3], Presence::AllPresent),
1062 ("street", vec![Some("Rue"); 3], Presence::AllPresent),
1063 ],
1064 )
1065 .unwrap();
1066
1067 layer_buf(staged_layer(
1068 "test",
1069 StagedId::None,
1070 three_points(),
1071 vec![
1072 StagedProperty::str("before", ["a", "a", "a"]),
1073 StagedProperty::u32("count", vec![1, 2, 3]),
1074 StagedProperty::SharedDict(shared_dict),
1075 StagedProperty::str("after", ["b", "b", "b"]),
1076 ],
1077 ))
1078 }
1079
1080 const BOTH_ENDS_NAMES: [&str; 6] = [
1081 "before",
1082 "count",
1083 "addr:city",
1084 "addr:zip",
1085 "addr:street",
1086 "after",
1087 ];
1088
1089 fn prop_names() -> Vec<PropName<'static>> {
1090 BOTH_ENDS_NAMES.iter().map(|n| PropName(n, "")).collect()
1091 }
1092
1093 #[test]
1094 fn prop_names_iterate_from_both_ends_lazy() {
1095 let buf = both_ends_layer();
1096 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1097 let Layer::Tag01(lazy) = layer else { panic!() };
1098
1099 assert_eq!(strs(lazy.iterate_prop_names()), BOTH_ENDS_NAMES);
1100 assert_eq!(reversed(lazy.iterate_prop_names()), BOTH_ENDS_NAMES);
1101 assert_size_hint_exact(|| lazy.iterate_prop_names(), &prop_names());
1102 }
1103
1104 #[test]
1105 fn prop_names_iterate_from_both_ends_parsed() {
1106 let buf = both_ends_layer();
1107 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1108 let Layer::Tag01(lazy) = layer else { panic!() };
1109 let parsed = lazy.decode_all(&mut dec()).unwrap();
1110
1111 assert_eq!(strs(parsed.iterate_prop_names()), BOTH_ENDS_NAMES);
1112 assert_eq!(reversed(parsed.iterate_prop_names()), BOTH_ENDS_NAMES);
1113
1114 assert_size_hint_exact(|| parsed.iterate_prop_names(), &prop_names());
1115 }
1116
1117 #[test]
1118 fn prop_names_of_layer_without_properties() {
1119 let buf = layer_buf(empty_layer("test"));
1120 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1121 let Layer::Tag01(lazy) = layer else { panic!() };
1122
1123 assert_eq!(lazy.iterate_prop_names().size_hint(), (0, Some(0)));
1124 assert_eq!(lazy.iterate_prop_names().next(), None);
1125 assert_eq!(lazy.iterate_prop_names().next_back(), None);
1126
1127 let parsed = lazy.decode_all(&mut dec()).unwrap();
1128 assert_eq!(parsed.iterate_prop_names().size_hint(), (0, Some(0)));
1129 assert_eq!(parsed.iterate_prop_names().next(), None);
1130 assert_eq!(parsed.iterate_prop_names().next_back(), None);
1131 }
1132
1133 #[test]
1136 fn prop_names_skip_columns_that_failed_to_parse() {
1137 let buf = both_ends_layer();
1138 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1139 let Layer::Tag01(lazy) = layer else { panic!() };
1140 let raw = lazy.properties.clone();
1141
1142 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1143 let Layer::Tag01(lazy) = layer else { panic!() };
1144 let parsed = lazy.decode_all(&mut dec()).unwrap().properties;
1145
1146 let mixed = vec![
1147 raw[0].clone(),
1148 LazyParsed::ParsingFailed,
1149 LazyParsed::Parsed(parsed[2].clone()),
1150 LazyParsed::ParsingFailed,
1151 raw[3].clone(),
1152 ];
1153 let expected = ["before", "addr:city", "addr:zip", "addr:street", "after"];
1154
1155 assert_eq!(strs(PropNamesIter::new(&mixed)), expected);
1156 assert_eq!(reversed(PropNamesIter::new(&mixed)), expected);
1157 assert_size_hint_exact(
1158 || PropNamesIter::new(&mixed),
1159 &expected.map(|n| PropName(n, "")),
1160 );
1161
1162 let all_failed = vec![LazyParsed::ParsingFailed; 3];
1163 assert_eq!(PropNamesIter::new(&all_failed).size_hint(), (0, Some(0)));
1164 assert_eq!(PropNamesIter::new(&all_failed).next(), None);
1165 assert_eq!(PropNamesIter::new(&all_failed).next_back(), None);
1166 }
1167
1168 #[test]
1169 fn feature_property_iterators_run_backwards() {
1170 let buf = both_ends_layer();
1171 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1172 let Layer::Tag01(lazy) = layer else { panic!() };
1173 let parsed = lazy.decode_all(&mut dec()).unwrap();
1174
1175 let mut iter = parsed.iter_features();
1176 let feat = iter.next().unwrap().unwrap();
1177
1178 let all: Vec<_> = feat.iter_all_properties().collect();
1179 assert_size_hint_exact(|| feat.iter_all_properties(), &all);
1180 let mut all_back: Vec<_> = feat.iter_all_properties().rev().collect();
1181 all_back.reverse();
1182 assert_eq!(all_back, all);
1183
1184 let mut props_back: Vec<_> = feat
1185 .iter_properties()
1186 .rev()
1187 .map(|c| c.name().to_string())
1188 .collect();
1189 props_back.reverse();
1190 assert_eq!(props_back, BOTH_ENDS_NAMES);
1191 }
1192}