1use std::fmt;
2use std::num::NonZeroU32;
3
4use super::feature::MvtFeatureRef;
5use super::property::{MvtValueRef, value_ref};
6use crate::generated::vector_tile::tile as proto_tile;
7use crate::{DEFAULT_EXTENT, MvtError, MvtLayer, MvtResult};
8
9#[derive(Copy, Clone)]
10pub struct MvtLayerRef<'a>(&'a proto_tile::LayerView<'a>);
11
12impl<'a> MvtLayerRef<'a> {
13 pub(crate) fn new(view: &'a proto_tile::LayerView<'a>) -> Self {
14 Self(view)
15 }
16
17 #[must_use]
18 pub fn name(self) -> &'a str {
19 self.0.name
20 }
21
22 #[must_use]
23 pub fn version(self) -> u32 {
24 self.0.version
25 }
26
27 #[must_use]
28 pub fn extent(self) -> u32 {
29 self.0.extent.unwrap_or(DEFAULT_EXTENT.get())
30 }
31
32 #[must_use]
33 pub fn feature_count(self) -> usize {
34 self.0.features.len()
35 }
36
37 #[must_use]
38 pub fn is_empty(self) -> bool {
39 self.0.features.is_empty()
40 }
41
42 #[must_use]
43 pub fn keys(self) -> &'a [&'a str] {
44 &self.0.keys
45 }
46
47 #[must_use]
48 pub fn values(self) -> impl ExactSizeIterator<Item = MvtValueRef<'a>> {
49 self.0.values.iter().map(value_ref)
50 }
51
52 #[must_use]
53 pub fn features(self) -> impl ExactSizeIterator<Item = MvtFeatureRef<'a>> {
54 self.0
55 .features
56 .iter()
57 .map(move |feature| MvtFeatureRef::new(self.0, feature))
58 }
59
60 pub fn to_layer(self) -> MvtResult<MvtLayer> {
61 let extent = match self.0.extent {
62 Some(extent) => NonZeroU32::new(extent).ok_or(MvtError::InvalidExtent)?,
63 None => DEFAULT_EXTENT,
64 };
65 self.features()
66 .map(MvtFeatureRef::to_feature)
67 .collect::<MvtResult<Vec<_>>>()
68 .map(|features| MvtLayer {
69 name: self.0.name.to_string(),
70 extent,
71 features,
72 })
73 }
74}
75
76impl fmt::Debug for MvtLayerRef<'_> {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 writeln!(f, " name: {}", self.name())?;
79 writeln!(f, " version: {}", self.version())?;
80 writeln!(f, " extent: {}", self.extent())?;
81 for (index, feature) in self.features().enumerate() {
82 writeln!(f, " feature: {index}")?;
83 write!(f, "{feature:?}")?;
85 }
86 Ok(())
87 }
88}