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 Self::Bool(_)
303 | Self::I8(_)
304 | Self::U8(_)
305 | Self::I32(_)
306 | Self::U32(_)
307 | Self::I64(_)
308 | Self::U64(_)
309 | Self::F32(_)
310 | Self::F64(_)
311 | Self::Str(_) => 1,
312 }
313 }
314
315 fn name_at(&self, idx: usize) -> PropName<'p> {
316 use ParsedProperty as P;
317 match self {
318 P::Bool(s) => PropName(s.name, ""),
319 P::I8(s) => PropName(s.name, ""),
320 P::U8(s) => PropName(s.name, ""),
321 P::I32(s) => PropName(s.name, ""),
322 P::U32(s) => PropName(s.name, ""),
323 P::I64(s) => PropName(s.name, ""),
324 P::U64(s) => PropName(s.name, ""),
325 P::F32(s) => PropName(s.name, ""),
326 P::F64(s) => PropName(s.name, ""),
327 P::Str(s) => PropName(s.name, ""),
328 P::SharedDict(sd) => PropName(sd.prefix, sd.items[idx].suffix),
329 }
330 }
331}
332
333impl<'p> ColNames for RawProperty<'p> {
334 type Name = PropName<'p>;
335
336 fn name_count(&self) -> usize {
337 match self {
338 Self::SharedDict(sd) => sd.children.len(),
339 Self::Bool(_)
340 | Self::I8(_)
341 | Self::U8(_)
342 | Self::I32(_)
343 | Self::U32(_)
344 | Self::I64(_)
345 | Self::U64(_)
346 | Self::F32(_)
347 | Self::F64(_)
348 | Self::Str(_) => 1,
349 }
350 }
351
352 fn name_at(&self, idx: usize) -> PropName<'p> {
353 use RawProperty as P;
354 match self {
355 P::Bool(s)
356 | P::I8(s)
357 | P::U8(s)
358 | P::I32(s)
359 | P::U32(s)
360 | P::I64(s)
361 | P::U64(s)
362 | P::F32(s)
363 | P::F64(s) => PropName(s.name, ""),
364 P::Str(s) => PropName(s.name, ""),
365 P::SharedDict(sd) => PropName(sd.name, sd.children[idx].name),
366 }
367 }
368}
369
370impl<'p> ColNames for LazyParsed<RawProperty<'p>, ParsedProperty<'p>> {
372 type Name = PropName<'p>;
373
374 fn name_count(&self) -> usize {
375 match self {
376 Self::Raw(r) => r.name_count(),
377 Self::Parsed(p) => p.name_count(),
378 Self::ParsingFailed => 0,
379 }
380 }
381
382 fn name_at(&self, idx: usize) -> PropName<'p> {
383 match self {
384 Self::Raw(r) => r.name_at(idx),
385 Self::Parsed(p) => p.name_at(idx),
386 Self::ParsingFailed => unreachable!("ParsingFailed contributes no names"),
387 }
388 }
389}
390
391#[must_use]
396pub struct PropNamesIter<'a, C> {
397 props: &'a [C],
398 cols: Range<usize>,
401 front_sub: usize,
403 back_sub: usize,
405 remaining: usize,
408}
409
410impl<'a, C: ColNames> PropNamesIter<'a, C> {
411 pub(crate) fn new(props: &'a [C]) -> Self {
412 Self {
413 props,
414 cols: 0..props.len(),
415 front_sub: 0,
416 back_sub: props.last().map_or(0, ColNames::name_count),
417 remaining: props.iter().map(ColNames::name_count).sum(),
418 }
419 }
420}
421
422impl<C: ColNames> Iterator for PropNamesIter<'_, C> {
423 type Item = C::Name;
424
425 fn next(&mut self) -> Option<C::Name> {
426 if self.remaining == 0 {
427 return None;
428 }
429 self.remaining -= 1;
430 loop {
431 let col = &self.props[self.cols.start];
433 if self.front_sub < col.name_count() {
434 let name = col.name_at(self.front_sub);
435 self.front_sub += 1;
436 return Some(name);
437 }
438 self.cols.start += 1;
439 self.front_sub = 0;
440 }
441 }
442
443 fn size_hint(&self) -> (usize, Option<usize>) {
444 (self.remaining, Some(self.remaining))
445 }
446}
447
448impl<C: ColNames> DoubleEndedIterator for PropNamesIter<'_, C> {
449 fn next_back(&mut self) -> Option<C::Name> {
450 if self.remaining == 0 {
451 return None;
452 }
453 self.remaining -= 1;
454 loop {
455 if self.back_sub > 0 {
456 self.back_sub -= 1;
457 return Some(self.props[self.cols.end - 1].name_at(self.back_sub));
458 }
459 self.cols.end -= 1;
460 self.back_sub = self.props[self.cols.end - 1].name_count();
461 }
462 }
463}
464
465impl<C: ColNames> ExactSizeIterator for PropNamesIter<'_, C> {
466 fn len(&self) -> usize {
467 self.remaining
468 }
469}
470
471impl<C: ColNames> FusedIterator for PropNamesIter<'_, C> {}
472
473type ColValIter<'l> = Box<dyn Iterator<Item = Option<PropValueRef<'l>>> + 'l>;
475
476fn build_col_iters<'p>(columns: &'p [ParsedProperty<'p>]) -> Vec<ColValIter<'p>> {
481 use ParsedProperty as PP;
482 let mut iters: Vec<ColValIter<'p>> = Vec::new();
483 for col in columns {
484 match col {
485 PP::Bool(s) => iters.push(scalar_col_iter(s)),
486 PP::I8(s) => iters.push(scalar_col_iter(s)),
487 PP::U8(s) => iters.push(scalar_col_iter(s)),
488 PP::I32(s) => iters.push(scalar_col_iter(s)),
489 PP::U32(s) => iters.push(scalar_col_iter(s)),
490 PP::I64(s) => iters.push(scalar_col_iter(s)),
491 PP::U64(s) => iters.push(scalar_col_iter(s)),
492 PP::F32(s) => iters.push(scalar_col_iter(s)),
493 PP::F64(s) => iters.push(scalar_col_iter(s)),
494 PP::Str(strings) => {
495 let data: &'p str = strings.data.as_ref();
496 let lengths: &'p [i32] = &strings.lengths;
497 let mut curr_end: usize = 0;
498 let mut feat_idx = 0usize;
499 iters.push(Box::new(std::iter::from_fn(move || {
500 let &end_i32 = lengths.get(feat_idx)?;
501 feat_idx += 1;
502 if end_i32 >= 0 {
503 let start = curr_end;
504 curr_end = end_i32.cast_unsigned().into_usize();
505 Some(data.get(start..curr_end).map(PropValueRef::Str))
506 } else {
507 Some(None)
509 }
510 })));
511 }
512 PP::SharedDict(dict) => {
513 for item in &dict.items {
514 let dict_ref: &'p _ = dict;
515 let item_ref: &'p _ = item;
516 let mut feat_idx = 0usize;
517 iters.push(Box::new(std::iter::from_fn(move || {
518 if feat_idx >= item_ref.ranges.len() {
519 return None;
520 }
521 let idx = feat_idx;
522 feat_idx += 1;
523 Some(item_ref.get(dict_ref, idx).map(PropValueRef::Str))
524 })));
525 }
526 }
527 }
528 }
529 iters
530}
531
532fn scalar_col_iter<'p, T>(scalar: &'p ParsedScalar<'p, T>) -> ColValIter<'p>
534where
535 T: Copy + PartialEq,
536 PropValueRef<'p>: From<T>,
537{
538 Box::new(scalar.iter_optional().map(|o| o.map(PropValueRef::from)))
539}
540
541pub struct Layer01FeatureIter<'layer, 'data: 'layer> {
551 layer: &'layer Layer01<'data, Parsed>,
552 index: usize,
553 feature_count: usize,
554 id_iter: Option<crate::utils::PresenceOptIter<'layer, u64>>,
556 col_iters: Vec<ColValIter<'layer>>,
558 values_buf: Vec<Option<PropValueRef<'layer>>>,
560}
561
562impl<'layer, 'data: 'layer> Layer01FeatureIter<'layer, 'data> {
563 fn new(layer: &'layer Layer01<'data, Parsed>) -> Self {
564 let col_iters = build_col_iters(&layer.properties);
565 let cap = col_iters.len();
566 Self {
567 layer,
568 index: 0,
569 feature_count: layer.feature_count(),
570 id_iter: layer.id.as_ref().map(|id| id.iter_optional()),
571 col_iters,
572 values_buf: Vec::with_capacity(cap),
573 }
574 }
575
576 #[must_use]
578 pub fn len(&self) -> usize {
579 self.feature_count - self.index
580 }
581
582 #[must_use]
584 pub fn is_empty(&self) -> bool {
585 self.index >= self.feature_count
586 }
587}
588
589impl<'layer> LendingIterator for Layer01FeatureIter<'layer, '_> {
590 type Item<'this>
591 = MltResult<FeatureRef<'this, 'layer>>
592 where
593 Self: 'this;
594
595 fn next(&mut self) -> Option<Self::Item<'_>> {
596 let index = self.index;
597 if index >= self.feature_count {
598 return None;
599 }
600 self.index += 1;
601
602 let id = self.id_iter.as_mut().and_then(Iterator::next).flatten();
605 self.values_buf.clear();
606 self.values_buf
607 .extend(self.col_iters.iter_mut().map(|it| it.next().flatten()));
608
609 Some(
610 self.layer
611 .geometry
612 .to_geojson(index)
613 .map(|geometry| FeatureRef {
614 id,
615 geometry,
616 columns: &self.layer.properties,
617 values: &self.values_buf,
618 }),
619 )
620 }
621}
622
623#[cfg(test)]
624mod tests {
625 use geo_types::Point;
626 use serde_json::Value;
627
628 use super::*;
629 use crate::Layer;
630 use crate::decoder::GeometryValues;
631 use crate::encoder::model::StagedLayer;
632 use crate::encoder::{Codecs, Encoder, Presence, StagedId, StagedProperty, StagedSharedDict};
633 use crate::test_helpers::{assert_size_hint_exact, dec, parser};
634
635 fn layer_buf(staged: StagedLayer) -> Vec<u8> {
636 staged
637 .encode_into(Encoder::default(), &mut Codecs::default())
638 .unwrap()
639 .into_layer_bytes()
640 .unwrap()
641 }
642
643 fn three_points() -> GeometryValues {
644 let mut g = GeometryValues::default();
645 g.push_geom(&Geometry::<i32>::Point(Point::new(1, 2)));
646 g.push_geom(&Geometry::<i32>::Point(Point::new(3, 4)));
647 g.push_geom(&Geometry::<i32>::Point(Point::new(5, 6)));
648 g
649 }
650
651 fn empty_layer(name: &str) -> StagedLayer {
652 staged_layer(name, StagedId::None, GeometryValues::default(), vec![])
653 }
654
655 fn staged_layer(
656 name: &str,
657 id: StagedId,
658 geometry: GeometryValues,
659 properties: Vec<StagedProperty>,
660 ) -> StagedLayer {
661 StagedLayer::new(name, 4096, id, geometry, properties).unwrap()
662 }
663
664 #[test]
665 fn prop_name_display_concatenates_parts() {
666 assert_eq!(PropName("addr:", "city").to_string(), "addr:city");
667 assert_eq!(PropName("name", "").to_string(), "name");
668 assert_eq!(PropName("", "").to_string(), "");
669 }
670
671 #[test]
672 fn prop_name_eq_str_matches_concatenation() {
673 assert_eq!(PropName("addr:", "city"), "addr:city");
674 assert_eq!("addr:city", PropName("addr:", "city"));
675 assert_ne!(PropName("addr:", "city"), "addr:");
676 assert_ne!(PropName("addr:", "city"), "city");
677 assert_eq!(PropName("name", ""), "name");
678 }
679
680 #[test]
681 fn prop_name_structural_eq_is_part_wise() {
682 assert_eq!(PropName("a", "b"), PropName("a", "b"));
683 assert_eq!(PropName("ab", ""), PropName("a", "b"));
684 }
685
686 #[test]
687 fn prop_name_eq_prop_name_semantic_equality() {
688 assert_eq!(PropName("ab", ""), PropName("a", "b"));
689 assert_eq!(PropName("", "ab"), PropName("a", "b"));
690 assert_eq!(PropName("abc", "def"), PropName("ab", "cdef"));
691 assert_eq!(PropName("a", "bcdef"), PropName("abcde", "f"));
692
693 assert_ne!(PropName("a", "b"), PropName("a", "c"));
694 assert_ne!(PropName("a", "b"), PropName("ab", "c"));
695 assert_ne!(PropName("abc", ""), PropName("ab", ""));
696 }
697
698 #[test]
699 fn prop_value_ref_scalars_convert_to_json() {
700 assert_eq!(Value::from(PropValueRef::Bool(true)), Value::Bool(true));
701 assert_eq!(Value::from(PropValueRef::Bool(false)), Value::Bool(false));
702 assert_eq!(Value::from(PropValueRef::I8(-1)), Value::from(-1_i8));
703 assert_eq!(Value::from(PropValueRef::U8(255)), Value::from(255_u8));
704 assert_eq!(
705 Value::from(PropValueRef::I32(-1000)),
706 Value::from(-1000_i32)
707 );
708 assert_eq!(Value::from(PropValueRef::U32(1000)), Value::from(1000_u32));
709 assert_eq!(
710 Value::from(PropValueRef::I64(i64::MIN)),
711 Value::from(i64::MIN)
712 );
713 assert_eq!(
714 Value::from(PropValueRef::U64(u64::MAX)),
715 Value::from(u64::MAX)
716 );
717 assert_eq!(
718 Value::from(PropValueRef::Str("hello")),
719 Value::String("hello".into())
720 );
721 }
722
723 #[test]
724 fn prop_value_ref_float_finite_is_number() {
725 assert!(matches!(
726 Value::from(PropValueRef::F32(1.5)),
727 Value::Number(_)
728 ));
729 assert!(matches!(
730 Value::from(PropValueRef::F64(2.5)),
731 Value::Number(_)
732 ));
733 }
734
735 #[test]
736 fn prop_value_ref_float_non_finite_becomes_string_sentinel() {
737 assert_eq!(
738 Value::from(PropValueRef::F32(f32::NAN)),
739 Value::String("f32::NAN".into())
740 );
741 assert_eq!(
742 Value::from(PropValueRef::F32(f32::INFINITY)),
743 Value::String("f32::INFINITY".into())
744 );
745 assert_eq!(
746 Value::from(PropValueRef::F64(f64::NAN)),
747 Value::String("f64::NAN".into())
748 );
749 assert_eq!(
750 Value::from(PropValueRef::F64(f64::NEG_INFINITY)),
751 Value::String("f64::NEG_INFINITY".into())
752 );
753 }
754
755 #[test]
756 fn empty_layer_yields_no_features() {
757 let buf = layer_buf(empty_layer("empty"));
758 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
759 let Layer::Tag01(lazy) = layer else {
760 panic!("expected Tag01")
761 };
762 let parsed = lazy.decode_all(&mut dec()).unwrap();
763
764 let iter = parsed.iter_features();
765 assert_eq!(iter.len(), 0);
766 assert!(iter.is_empty());
767 assert_eq!(parsed.iter_features().len(), 0);
768 }
769
770 #[test]
771 fn len_decreases_with_each_next() {
772 let buf = layer_buf(staged_layer("test", StagedId::None, three_points(), vec![]));
773 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
774 let Layer::Tag01(lazy) = layer else { panic!() };
775 let parsed = lazy.decode_all(&mut dec()).unwrap();
776
777 let mut iter = parsed.iter_features();
778 assert_eq!(iter.len(), 3);
779 iter.next().unwrap().unwrap();
780 assert_eq!(iter.len(), 2);
781 iter.next().unwrap().unwrap();
782 assert_eq!(iter.len(), 1);
783 iter.next().unwrap().unwrap();
784 assert_eq!(iter.len(), 0);
785 assert!(iter.is_empty());
786 assert!(iter.next().is_none());
787 }
788
789 #[test]
790 fn feature_ids_are_preserved() {
791 let buf = layer_buf(staged_layer(
792 "test",
793 StagedId::from_optional(vec![Some(100), None, Some(200)]),
794 three_points(),
795 vec![],
796 ));
797 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
798 let Layer::Tag01(lazy) = layer else { panic!() };
799 let parsed = lazy.decode_all(&mut dec()).unwrap();
800
801 let mut ids = Vec::new();
802 let mut iter = parsed.iter_features();
803 while let Some(r) = iter.next() {
804 ids.push(r.unwrap().id);
805 }
806 assert_eq!(ids, [Some(100), None, Some(200)]);
807 }
808
809 #[test]
810 fn geometry_values_match_input() {
811 let buf = layer_buf(staged_layer("test", StagedId::None, three_points(), vec![]));
812 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
813 let Layer::Tag01(lazy) = layer else { panic!() };
814 let parsed = lazy.decode_all(&mut dec()).unwrap();
815
816 let mut geoms = Vec::new();
817 let mut iter = parsed.iter_features();
818 while let Some(r) = iter.next() {
819 geoms.push(r.unwrap().geometry);
820 }
821 assert_eq!(geoms[0], Geometry::<i32>::Point(Point::new(1, 2)));
822 assert_eq!(geoms[1], Geometry::<i32>::Point(Point::new(3, 4)));
823 assert_eq!(geoms[2], Geometry::<i32>::Point(Point::new(5, 6)));
824 }
825
826 #[test]
827 fn null_scalar_values_are_skipped() {
828 let buf = layer_buf(staged_layer(
829 "test",
830 StagedId::None,
831 three_points(),
832 vec![StagedProperty::opt_u32("n", vec![Some(1), None, Some(3)])],
833 ));
834 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
835 let Layer::Tag01(lazy) = layer else { panic!() };
836 let parsed = lazy.decode_all(&mut dec()).unwrap();
837
838 let mut iter = parsed.iter_features();
839
840 {
841 let feat = iter.next().unwrap().unwrap();
842 let cols: Vec<_> = feat.iter_properties().collect();
843 assert_eq!(cols.len(), 1);
844 assert_eq!(cols[0].name, PropName("n", ""));
845 assert_eq!(cols[0].name, "n");
846 assert_eq!(cols[0].value, PropValueRef::U32(1));
847 let all: Vec<_> = feat.iter_all_properties().collect();
848 assert_eq!(all, [Some(PropValueRef::U32(1))]);
849 }
850 {
851 let feat = iter.next().unwrap().unwrap();
852 assert!(feat.iter_properties().next().is_none());
853 let all: Vec<_> = feat.iter_all_properties().collect();
854 assert_eq!(all, [None]);
855 }
856 {
857 let feat = iter.next().unwrap().unwrap();
858 assert_eq!(feat.get_property("n"), Some(PropValueRef::U32(3)));
859 let all: Vec<_> = feat.iter_all_properties().collect();
860 assert_eq!(all, [Some(PropValueRef::U32(3))]);
861 }
862
863 let names: Vec<_> = parsed.iterate_prop_names().map(|n| n.to_string()).collect();
864 assert_eq!(names, ["n"]);
865 }
866
867 #[test]
868 fn null_string_values_are_skipped() {
869 let buf = layer_buf(staged_layer(
870 "test",
871 StagedId::None,
872 three_points(),
873 vec![StagedProperty::opt_str(
874 "label",
875 vec![Some("foo"), None, Some("bar")],
876 )],
877 ));
878 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
879 let Layer::Tag01(lazy) = layer else { panic!() };
880 let parsed = lazy.decode_all(&mut dec()).unwrap();
881
882 let mut iter = parsed.iter_features();
883 {
884 let feat = iter.next().unwrap().unwrap();
885 assert_eq!(feat.get_property("label"), Some(PropValueRef::Str("foo")));
886 }
887 {
888 let feat = iter.next().unwrap().unwrap();
889 assert_eq!(feat.get_property("label"), None);
890 }
891 {
892 let feat = iter.next().unwrap().unwrap();
893 assert_eq!(feat.get_property("label"), Some(PropValueRef::Str("bar")));
894 }
895 }
896
897 #[test]
898 fn multiple_columns_independently_nullable() {
899 let buf = layer_buf(staged_layer(
900 "test",
901 StagedId::None,
902 three_points(),
903 vec![
904 StagedProperty::opt_bool("flag", vec![Some(true), Some(false), None]),
905 StagedProperty::opt_i32("score", vec![None, Some(-5), Some(7)]),
906 ],
907 ));
908 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
909 let Layer::Tag01(lazy) = layer else { panic!() };
910 let parsed = lazy.decode_all(&mut dec()).unwrap();
911
912 let mut iter = parsed.iter_features();
913
914 {
916 let feat = iter.next().unwrap().unwrap();
917 assert_eq!(feat.iter_properties().count(), 1);
918 assert_eq!(feat.get_property("flag"), Some(PropValueRef::Bool(true)));
919 assert_eq!(feat.get_property("score"), None);
920 }
921 {
923 let feat = iter.next().unwrap().unwrap();
924 assert_eq!(feat.iter_properties().count(), 2);
925 assert_eq!(feat.get_property("flag"), Some(PropValueRef::Bool(false)));
926 assert_eq!(feat.get_property("score"), Some(PropValueRef::I32(-5)));
927 }
928 {
930 let feat = iter.next().unwrap().unwrap();
931 assert_eq!(feat.iter_properties().count(), 1);
932 assert_eq!(feat.get_property("flag"), None);
933 assert_eq!(feat.get_property("score"), Some(PropValueRef::I32(7)));
934 }
935 }
936
937 #[test]
938 fn geometry_error_does_not_misalign_ids() {
939 use crate::decoder::GeometryType;
940
941 let buf = layer_buf(staged_layer(
942 "test",
943 StagedId::from_optional(vec![Some(10), Some(20), Some(30)]),
944 three_points(),
945 vec![],
946 ));
947 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
948 let Layer::Tag01(lazy) = layer else { panic!() };
949 let mut parsed = lazy.decode_all(&mut dec()).unwrap();
950
951 parsed.geometry.vector_types[1] = GeometryType::LineString;
955
956 let mut iter = parsed.iter_features();
957
958 let feat0 = iter.next().unwrap().unwrap();
960 assert_eq!(feat0.id, Some(10));
961
962 assert!(iter.next().unwrap().is_err());
964
965 let feat2 = iter.next().unwrap().unwrap();
967 assert_eq!(
968 feat2.id,
969 Some(30),
970 "id cursor was not advanced on geometry error"
971 );
972
973 assert!(iter.next().is_none());
974 }
975
976 #[test]
977 fn get_property_absent_column_returns_none() {
978 let buf = layer_buf(staged_layer(
979 "test",
980 StagedId::None,
981 three_points(),
982 vec![StagedProperty::u32("x", vec![1, 2, 3])],
983 ));
984 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
985 let Layer::Tag01(lazy) = layer else { panic!() };
986 let parsed = lazy.decode_all(&mut dec()).unwrap();
987
988 let mut iter = parsed.iter_features();
989 let feat = iter.next().unwrap().unwrap();
990 assert_eq!(feat.get_property("no_such_column"), None);
991 }
992
993 #[test]
994 fn shared_dict_columns_are_expanded() {
995 let shared_dict = StagedSharedDict::new(
996 "addr:",
997 [
998 (
999 "city",
1000 vec![Some("Paris"), Some("Rome"), None],
1001 Presence::Mixed,
1002 ),
1003 (
1004 "zip",
1005 vec![Some("75001"), None, Some("00100")],
1006 Presence::Mixed,
1007 ),
1008 ],
1009 )
1010 .unwrap();
1011
1012 let buf = layer_buf(staged_layer(
1013 "test",
1014 StagedId::None,
1015 three_points(),
1016 vec![StagedProperty::SharedDict(shared_dict)],
1017 ));
1018 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1019 let Layer::Tag01(lazy) = layer else { panic!() };
1020 let parsed = lazy.decode_all(&mut dec()).unwrap();
1021
1022 let mut iter = parsed.iter_features();
1023
1024 {
1026 let feat = iter.next().unwrap().unwrap();
1027 assert_eq!(
1028 feat.get_property("addr:city"),
1029 Some(PropValueRef::Str("Paris"))
1030 );
1031 assert_eq!(
1032 feat.get_property("addr:zip"),
1033 Some(PropValueRef::Str("75001"))
1034 );
1035 assert_eq!(feat.iter_properties().count(), 2);
1036 }
1037 {
1039 let feat = iter.next().unwrap().unwrap();
1040 assert_eq!(
1041 feat.get_property("addr:city"),
1042 Some(PropValueRef::Str("Rome"))
1043 );
1044 assert_eq!(feat.get_property("addr:zip"), None);
1045 assert_eq!(feat.iter_properties().count(), 1);
1046 let all: Vec<_> = feat.iter_all_properties().collect();
1048 assert_eq!(all, [Some(PropValueRef::Str("Rome")), None]);
1049 }
1050 {
1052 let feat = iter.next().unwrap().unwrap();
1053 assert_eq!(feat.get_property("addr:city"), None);
1054 assert_eq!(
1055 feat.get_property("addr:zip"),
1056 Some(PropValueRef::Str("00100"))
1057 );
1058 }
1059
1060 let names: Vec<_> = parsed.iterate_prop_names().map(|n| n.to_string()).collect();
1061 assert_eq!(names, ["addr:city", "addr:zip"]);
1062 }
1063
1064 fn strs<'p>(iter: impl Iterator<Item = PropName<'p>>) -> Vec<String> {
1065 iter.map(|n| n.to_string()).collect()
1066 }
1067
1068 fn reversed<'p>(iter: impl DoubleEndedIterator<Item = PropName<'p>>) -> Vec<String> {
1069 let mut names = strs(iter.rev());
1070 names.reverse();
1071 names
1072 }
1073
1074 fn both_ends_layer() -> Vec<u8> {
1075 let shared_dict = StagedSharedDict::new(
1076 "addr:",
1077 [
1078 ("city", vec![Some("Paris"); 3], Presence::AllPresent),
1079 ("zip", vec![Some("75001"); 3], Presence::AllPresent),
1080 ("street", vec![Some("Rue"); 3], Presence::AllPresent),
1081 ],
1082 )
1083 .unwrap();
1084
1085 layer_buf(staged_layer(
1086 "test",
1087 StagedId::None,
1088 three_points(),
1089 vec![
1090 StagedProperty::str("before", ["a", "a", "a"]),
1091 StagedProperty::u32("count", vec![1, 2, 3]),
1092 StagedProperty::SharedDict(shared_dict),
1093 StagedProperty::str("after", ["b", "b", "b"]),
1094 ],
1095 ))
1096 }
1097
1098 const BOTH_ENDS_NAMES: [&str; 6] = [
1099 "before",
1100 "count",
1101 "addr:city",
1102 "addr:zip",
1103 "addr:street",
1104 "after",
1105 ];
1106
1107 fn prop_names() -> Vec<PropName<'static>> {
1108 BOTH_ENDS_NAMES.iter().map(|n| PropName(n, "")).collect()
1109 }
1110
1111 #[test]
1112 fn prop_names_iterate_from_both_ends_lazy() {
1113 let buf = both_ends_layer();
1114 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1115 let Layer::Tag01(lazy) = layer else { panic!() };
1116
1117 assert_eq!(strs(lazy.iterate_prop_names()), BOTH_ENDS_NAMES);
1118 assert_eq!(reversed(lazy.iterate_prop_names()), BOTH_ENDS_NAMES);
1119 assert_size_hint_exact(|| lazy.iterate_prop_names(), &prop_names());
1120 }
1121
1122 #[test]
1123 fn prop_names_iterate_from_both_ends_parsed() {
1124 let buf = both_ends_layer();
1125 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1126 let Layer::Tag01(lazy) = layer else { panic!() };
1127 let parsed = lazy.decode_all(&mut dec()).unwrap();
1128
1129 assert_eq!(strs(parsed.iterate_prop_names()), BOTH_ENDS_NAMES);
1130 assert_eq!(reversed(parsed.iterate_prop_names()), BOTH_ENDS_NAMES);
1131
1132 assert_size_hint_exact(|| parsed.iterate_prop_names(), &prop_names());
1133 }
1134
1135 #[test]
1136 fn prop_names_of_layer_without_properties() {
1137 let buf = layer_buf(empty_layer("test"));
1138 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1139 let Layer::Tag01(lazy) = layer else { panic!() };
1140
1141 assert_eq!(lazy.iterate_prop_names().size_hint(), (0, Some(0)));
1142 assert_eq!(lazy.iterate_prop_names().next(), None);
1143 assert_eq!(lazy.iterate_prop_names().next_back(), None);
1144
1145 let parsed = lazy.decode_all(&mut dec()).unwrap();
1146 assert_eq!(parsed.iterate_prop_names().size_hint(), (0, Some(0)));
1147 assert_eq!(parsed.iterate_prop_names().next(), None);
1148 assert_eq!(parsed.iterate_prop_names().next_back(), None);
1149 }
1150
1151 #[test]
1154 fn prop_names_skip_columns_that_failed_to_parse() {
1155 let buf = both_ends_layer();
1156 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1157 let Layer::Tag01(lazy) = layer else { panic!() };
1158 let raw = lazy.properties.clone();
1159
1160 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1161 let Layer::Tag01(lazy) = layer else { panic!() };
1162 let parsed = lazy.decode_all(&mut dec()).unwrap().properties;
1163
1164 let mixed = vec![
1165 raw[0].clone(),
1166 LazyParsed::ParsingFailed,
1167 LazyParsed::Parsed(parsed[2].clone()),
1168 LazyParsed::ParsingFailed,
1169 raw[3].clone(),
1170 ];
1171 let expected = ["before", "addr:city", "addr:zip", "addr:street", "after"];
1172
1173 assert_eq!(strs(PropNamesIter::new(&mixed)), expected);
1174 assert_eq!(reversed(PropNamesIter::new(&mixed)), expected);
1175 assert_size_hint_exact(
1176 || PropNamesIter::new(&mixed),
1177 &expected.map(|n| PropName(n, "")),
1178 );
1179
1180 let all_failed = vec![LazyParsed::ParsingFailed; 3];
1181 assert_eq!(PropNamesIter::new(&all_failed).size_hint(), (0, Some(0)));
1182 assert_eq!(PropNamesIter::new(&all_failed).next(), None);
1183 assert_eq!(PropNamesIter::new(&all_failed).next_back(), None);
1184 }
1185
1186 #[test]
1187 fn feature_property_iterators_run_backwards() {
1188 let buf = both_ends_layer();
1189 let (_, layer) = Layer::from_bytes(&buf, &mut parser()).unwrap();
1190 let Layer::Tag01(lazy) = layer else { panic!() };
1191 let parsed = lazy.decode_all(&mut dec()).unwrap();
1192
1193 let mut iter = parsed.iter_features();
1194 let feat = iter.next().unwrap().unwrap();
1195
1196 let all: Vec<_> = feat.iter_all_properties().collect();
1197 assert_size_hint_exact(|| feat.iter_all_properties(), &all);
1198 let mut all_back: Vec<_> = feat.iter_all_properties().rev().collect();
1199 all_back.reverse();
1200 assert_eq!(all_back, all);
1201
1202 let mut props_back: Vec<_> = feat
1203 .iter_properties()
1204 .rev()
1205 .map(|c| c.name().to_string())
1206 .collect();
1207 props_back.reverse();
1208 assert_eq!(props_back, BOTH_ENDS_NAMES);
1209 }
1210}