mlt_core/decoder/
into_tile.rs1use crate::decoder::{Layer, Layer01, ParsedLayer, ParsedLayer01, ParsedProperty};
9#[cfg(feature = "unstable-v2")]
10use crate::decoder::{Layer02, MValueSpans, ParsedLayer02, ParsedMValue, ParsedNested};
11use crate::errors::AsMltError as _;
12#[cfg(feature = "unstable-v2")]
13use crate::tile::{MValue, NestedKind, NestedValue};
14use crate::tile::{PropValue, TileFeature, TileLayer};
15use crate::{Decoder, Lazy, LendingIterator, MltResult};
16
17struct TileParts {
19 name: String,
20 extent: u32,
21 names: Vec<String>,
22 features: Vec<TileFeature>,
23}
24
25impl TileParts {
26 fn finish(self) -> MltResult<TileLayer> {
27 TileLayer::from_parts(self.name, self.extent, self.names, self.features)
28 }
29}
30
31impl ParsedLayer01<'_> {
32 pub fn into_tile(self, dec: &mut Decoder) -> MltResult<TileLayer> {
35 self.collect_parts(dec)?.finish()
36 }
37
38 fn collect_parts(&self, dec: &mut Decoder) -> MltResult<TileParts> {
41 let name = self.name().to_string();
42 let extent = self.extent().get();
43 let names: Vec<String> = self.iterate_prop_names().map(|n| n.to_string()).collect();
44 let col_nulls = typed_nulls(&self.properties);
45 let mut features = dec.alloc::<TileFeature>(self.feature_count())?;
46 let mut feat_iter = self.iter_features();
47 while let Some(feat) = feat_iter.next() {
48 let feat = feat?;
49 let mut values = dec.alloc::<PropValue>(names.len())?;
50 for (col_idx, value) in feat.iter_all_properties().enumerate() {
51 values.push(match value {
52 Some(v) => v.into(),
53 None => col_nulls[col_idx].clone(),
54 });
55 }
56
57 charge_str_props(dec, &values)?;
58
59 features.push(TileFeature {
60 id: feat.id(),
61 geometry: feat.geometry().clone(),
62 properties: values,
63 #[cfg(feature = "unstable-v2")]
64 m_values: Vec::new(),
65 #[cfg(feature = "unstable-v2")]
66 nested: Vec::new(),
67 #[cfg(feature = "unstable-v2")]
68 z: Vec::new(),
69 });
70 }
71 Ok(TileParts {
72 name,
73 extent,
74 names,
75 features,
76 })
77 }
78}
79
80impl Layer01<'_> {
81 pub fn into_tile(self, dec: &mut Decoder) -> MltResult<TileLayer> {
83 self.decode_all(dec)?.into_tile(dec)
84 }
85}
86
87#[cfg(feature = "unstable-v2")]
88impl ParsedLayer02<'_> {
89 pub fn into_tile(self, dec: &mut Decoder) -> MltResult<TileLayer> {
92 let m_names: Vec<String> = self.m_values.iter().map(|m| m.name().to_string()).collect();
93 let nested_names: Vec<String> = self.nested.iter().map(|n| n.name().to_string()).collect();
94 let nested_kinds: Vec<NestedKind> = self.nested.iter().map(ParsedNested::kind).collect();
95 let mut m_spans = dec.alloc::<MValueSpans>(self.m_values.len())?;
99 m_spans.extend(self.m_values.iter().map(|m| m.spans(&self.layer.geometry)));
100
101 let geometry = &self.layer.geometry;
102 let mut parts = self.layer.collect_parts(dec)?;
103 for (index, feature) in parts.features.iter_mut().enumerate() {
104 feature.m_values = m_values_of(&self.m_values, &mut m_spans, dec)?;
105 feature.nested = nested_of(&self.nested, index, dec)?;
106 let run = geometry.z_run(index)?;
107 let mut z = dec.alloc::<i32>(run.len())?;
108 for value in run {
109 z.push(value?);
110 }
111 feature.z = z;
112 }
113 parts
114 .finish()?
115 .with_m_value_names(m_names)?
116 .with_nested(nested_names, nested_kinds)?
117 .with_z_step(geometry.z_step())
118 }
119}
120
121#[cfg(feature = "unstable-v2")]
122impl Layer02<'_> {
123 pub fn into_tile(self, dec: &mut Decoder) -> MltResult<TileLayer> {
125 self.decode_all(dec)?.into_tile(dec)
126 }
127}
128
129impl ParsedLayer<'_> {
130 pub fn into_tile(self, dec: &mut Decoder) -> MltResult<Option<TileLayer>> {
133 match self {
134 Self::Tag01(l) => l.into_tile(dec).map(Some),
135 #[cfg(feature = "unstable-v2")]
136 Self::Tag02(l) => l.into_tile(dec).map(Some),
137 Self::Unknown(_) => Ok(None),
138 }
139 }
140}
141
142impl Layer<'_, Lazy> {
143 pub fn into_tile(self, dec: &mut Decoder) -> MltResult<Option<TileLayer>> {
146 self.decode_all(dec)?.into_tile(dec)
147 }
148}
149
150#[cfg(feature = "unstable-v2")]
155fn m_values_of(
156 columns: &[ParsedMValue<'_>],
157 spans: &mut [MValueSpans<'_>],
158 dec: &mut Decoder,
159) -> MltResult<Vec<MValue>> {
160 let mut values = dec.alloc::<MValue>(columns.len())?;
161 for (column, spans) in columns.iter().zip(spans) {
162 let span = spans.next().transpose()?.flatten();
163 if let Some(span) = &span {
164 dec.consume(u32::try_from(column.values().row_bytes(span)).or_overflow()?)?;
165 }
166 values.push(column.values().row(column.name(), span)?);
167 }
168 Ok(values)
169}
170
171#[cfg(feature = "unstable-v2")]
173fn nested_of(
174 columns: &[ParsedNested<'_>],
175 index: usize,
176 dec: &mut Decoder,
177) -> MltResult<Vec<NestedValue>> {
178 let mut values = dec.alloc::<NestedValue>(columns.len())?;
179 for column in columns {
180 let value = column.row(index)?;
181 dec.consume(u32::try_from(value.heap_bytes()).or_overflow()?)?;
182 values.push(value);
183 }
184 Ok(values)
185}
186
187fn typed_nulls(properties: &[ParsedProperty<'_>]) -> Vec<PropValue> {
194 use ParsedProperty as PP;
195 use PropValue as PV;
196 let mut nulls = Vec::new();
197 for prop in properties {
198 match prop {
199 PP::Bool(_) => nulls.push(PV::Bool(None)),
200 PP::I8(_) => nulls.push(PV::I8(None)),
201 PP::U8(_) => nulls.push(PV::U8(None)),
202 PP::I32(_) => nulls.push(PV::I32(None)),
203 PP::U32(_) => nulls.push(PV::U32(None)),
204 PP::I64(_) => nulls.push(PV::I64(None)),
205 PP::U64(_) => nulls.push(PV::U64(None)),
206 PP::F32(_) => nulls.push(PV::F32(None)),
207 PP::F64(_) => nulls.push(PV::F64(None)),
208 PP::Str(_) => nulls.push(PV::Str(None)),
209 PP::SharedDict(d) => {
210 for _ in &d.items {
211 nulls.push(PV::Str(None));
212 }
213 }
214 }
215 }
216 nulls
217}
218
219fn charge_str_props(dec: &mut Decoder, props: &[PropValue]) -> MltResult<()> {
221 let str_bytes = props
222 .iter()
223 .filter_map(|p| {
224 if let PropValue::Str(Some(s)) = p {
225 Some(s.len())
226 } else {
227 None
228 }
229 })
230 .try_fold(0u32, |acc, n| {
231 acc.checked_add(u32::try_from(n).or_overflow()?)
232 .or_overflow()
233 })?;
234 if str_bytes > 0 {
235 dec.consume(str_bytes)?;
236 }
237 Ok(())
238}