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