mlt_core/decoder/
into_tile.rs1use crate::decoder::{Layer01, ParsedLayer01, ParsedProperty, PropValueRef};
9#[cfg(feature = "unstable-v2")]
10use crate::decoder::{MValueSpans, 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, LendingIterator, MltResult};
16
17impl ParsedLayer01<'_> {
18 pub fn into_tile(self, dec: &mut Decoder) -> MltResult<TileLayer> {
21 let name = self.name().to_string();
23 let extent = self.extent().get();
24 let names: Vec<String> = self.iterate_prop_names().map(|n| n.to_string()).collect();
25 let col_nulls = typed_nulls(&self.properties);
26 #[cfg(feature = "unstable-v2")]
27 let m_names: Vec<String> = self.m_values.iter().map(|m| m.name().to_string()).collect();
28 #[cfg(feature = "unstable-v2")]
29 let nested_names: Vec<String> = self.nested.iter().map(|n| n.name().to_string()).collect();
30 #[cfg(feature = "unstable-v2")]
31 let nested_kinds: Vec<NestedKind> = self.nested.iter().map(ParsedNested::kind).collect();
32 #[cfg(feature = "unstable-v2")]
36 let mut m_spans = dec.alloc::<MValueSpans>(self.m_values.len())?;
37 #[cfg(feature = "unstable-v2")]
38 m_spans.extend(self.m_values.iter().map(|m| m.spans(&self.geometry)));
39 let mut features = dec.alloc::<TileFeature>(self.feature_count())?;
40 #[cfg(feature = "unstable-v2")]
41 let mut index = 0_usize;
42 let mut feat_iter = self.iter_features();
43 while let Some(feat) = feat_iter.next() {
44 let feat = feat?;
45 let mut values = dec.alloc::<PropValue>(names.len())?;
46 for (col_idx, value) in feat.iter_all_properties().enumerate() {
47 values.push(match value {
48 Some(v) => prop_value_from_ref(v),
49 None => col_nulls[col_idx].clone(),
50 });
51 }
52
53 charge_str_props(dec, &values)?;
54
55 features.push(TileFeature {
56 id: feat.id(),
57 geometry: feat.geometry().clone(),
58 properties: values,
59 #[cfg(feature = "unstable-v2")]
60 m_values: m_values_of(&self.m_values, &mut m_spans, dec)?,
61 #[cfg(feature = "unstable-v2")]
62 nested: nested_of(&self.nested, index, dec)?,
63 });
64 #[cfg(feature = "unstable-v2")]
65 {
66 index += 1;
67 }
68 }
69
70 let layer = TileLayer::from_parts(name, extent, names, features)?;
71 #[cfg(feature = "unstable-v2")]
72 let layer = layer
73 .with_m_value_names(m_names)?
74 .with_nested(nested_names, nested_kinds)?;
75 Ok(layer)
76 }
77}
78
79impl Layer01<'_> {
80 pub fn into_tile(self, dec: &mut Decoder) -> MltResult<TileLayer> {
82 self.decode_all(dec)?.into_tile(dec)
83 }
84}
85
86#[cfg(feature = "unstable-v2")]
91fn m_values_of(
92 columns: &[ParsedMValue<'_>],
93 spans: &mut [MValueSpans<'_>],
94 dec: &mut Decoder,
95) -> MltResult<Vec<MValue>> {
96 let mut values = dec.alloc::<MValue>(columns.len())?;
97 for (column, spans) in columns.iter().zip(spans) {
98 let span = spans.next().transpose()?.flatten();
99 if let Some(span) = &span {
100 dec.consume(u32::try_from(column.values().row_bytes(span)).or_overflow()?)?;
101 }
102 values.push(column.values().row(column.name(), span)?);
103 }
104 Ok(values)
105}
106
107#[cfg(feature = "unstable-v2")]
109fn nested_of(
110 columns: &[ParsedNested<'_>],
111 index: usize,
112 dec: &mut Decoder,
113) -> MltResult<Vec<NestedValue>> {
114 let mut values = dec.alloc::<NestedValue>(columns.len())?;
115 for column in columns {
116 let value = column.row(index)?;
117 dec.consume(u32::try_from(value.heap_bytes()).or_overflow()?)?;
118 values.push(value);
119 }
120 Ok(values)
121}
122
123fn prop_value_from_ref(value: PropValueRef<'_>) -> PropValue {
126 match value {
127 PropValueRef::Bool(v) => PropValue::Bool(Some(v)),
128 PropValueRef::I8(v) => PropValue::I8(Some(v)),
129 PropValueRef::U8(v) => PropValue::U8(Some(v)),
130 PropValueRef::I32(v) => PropValue::I32(Some(v)),
131 PropValueRef::U32(v) => PropValue::U32(Some(v)),
132 PropValueRef::I64(v) => PropValue::I64(Some(v)),
133 PropValueRef::U64(v) => PropValue::U64(Some(v)),
134 PropValueRef::F32(v) => PropValue::F32(Some(v)),
135 PropValueRef::F64(v) => PropValue::F64(Some(v)),
136 PropValueRef::Str(s) => PropValue::Str(Some(s.to_string())),
137 }
138}
139
140fn typed_nulls(properties: &[ParsedProperty<'_>]) -> Vec<PropValue> {
147 use ParsedProperty as PP;
148 use PropValue as PV;
149 let mut nulls = Vec::new();
150 for prop in properties {
151 match prop {
152 PP::Bool(_) => nulls.push(PV::Bool(None)),
153 PP::I8(_) => nulls.push(PV::I8(None)),
154 PP::U8(_) => nulls.push(PV::U8(None)),
155 PP::I32(_) => nulls.push(PV::I32(None)),
156 PP::U32(_) => nulls.push(PV::U32(None)),
157 PP::I64(_) => nulls.push(PV::I64(None)),
158 PP::U64(_) => nulls.push(PV::U64(None)),
159 PP::F32(_) => nulls.push(PV::F32(None)),
160 PP::F64(_) => nulls.push(PV::F64(None)),
161 PP::Str(_) => nulls.push(PV::Str(None)),
162 PP::SharedDict(d) => {
163 for _ in &d.items {
164 nulls.push(PV::Str(None));
165 }
166 }
167 }
168 }
169 nulls
170}
171
172fn charge_str_props(dec: &mut Decoder, props: &[PropValue]) -> MltResult<()> {
174 let str_bytes = props
175 .iter()
176 .filter_map(|p| {
177 if let PropValue::Str(Some(s)) = p {
178 Some(s.len())
179 } else {
180 None
181 }
182 })
183 .try_fold(0u32, |acc, n| {
184 acc.checked_add(u32::try_from(n).or_overflow()?)
185 .or_overflow()
186 })?;
187 if str_bytes > 0 {
188 dec.consume(str_bytes)?;
189 }
190 Ok(())
191}