mlt_core/decoder/
into_tile.rs1use crate::decoder::{Layer, Layer01, ParsedLayer, ParsedLayer01, ParsedProperty, PropValueRef};
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) => prop_value_from_ref(v),
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 prop_value_from_ref(value: PropValueRef<'_>) -> PropValue {
190 match value {
191 PropValueRef::Bool(v) => PropValue::Bool(Some(v)),
192 PropValueRef::I8(v) => PropValue::I8(Some(v)),
193 PropValueRef::U8(v) => PropValue::U8(Some(v)),
194 PropValueRef::I32(v) => PropValue::I32(Some(v)),
195 PropValueRef::U32(v) => PropValue::U32(Some(v)),
196 PropValueRef::I64(v) => PropValue::I64(Some(v)),
197 PropValueRef::U64(v) => PropValue::U64(Some(v)),
198 PropValueRef::F32(v) => PropValue::F32(Some(v)),
199 PropValueRef::F64(v) => PropValue::F64(Some(v)),
200 PropValueRef::Str(s) => PropValue::Str(Some(s.to_string())),
201 }
202}
203
204fn typed_nulls(properties: &[ParsedProperty<'_>]) -> Vec<PropValue> {
211 use ParsedProperty as PP;
212 use PropValue as PV;
213 let mut nulls = Vec::new();
214 for prop in properties {
215 match prop {
216 PP::Bool(_) => nulls.push(PV::Bool(None)),
217 PP::I8(_) => nulls.push(PV::I8(None)),
218 PP::U8(_) => nulls.push(PV::U8(None)),
219 PP::I32(_) => nulls.push(PV::I32(None)),
220 PP::U32(_) => nulls.push(PV::U32(None)),
221 PP::I64(_) => nulls.push(PV::I64(None)),
222 PP::U64(_) => nulls.push(PV::U64(None)),
223 PP::F32(_) => nulls.push(PV::F32(None)),
224 PP::F64(_) => nulls.push(PV::F64(None)),
225 PP::Str(_) => nulls.push(PV::Str(None)),
226 PP::SharedDict(d) => {
227 for _ in &d.items {
228 nulls.push(PV::Str(None));
229 }
230 }
231 }
232 }
233 nulls
234}
235
236fn charge_str_props(dec: &mut Decoder, props: &[PropValue]) -> MltResult<()> {
238 let str_bytes = props
239 .iter()
240 .filter_map(|p| {
241 if let PropValue::Str(Some(s)) = p {
242 Some(s.len())
243 } else {
244 None
245 }
246 })
247 .try_fold(0u32, |acc, n| {
248 acc.checked_add(u32::try_from(n).or_overflow()?)
249 .or_overflow()
250 })?;
251 if str_bytes > 0 {
252 dec.consume(str_bytes)?;
253 }
254 Ok(())
255}