1use std::io::{Seek, Write};
2
3use crate::{
4    Array, ArrayType, array_type,
5    data::{write_checks::*, *},
6    error::Error,
7    file::zip_container::FileType,
8    pqarray::{PqArrayWriter, PqWriteOptions},
9};
10
11use super::super::{Compression, Writer};
12
13impl From<Compression> for PqWriteOptions {
14    fn from(value: Compression) -> Self {
15        Self {
16            compression_level: value.level(),
17            ..Default::default()
18        }
19    }
20}
21
22impl<W: Write + Seek + Send> Writer<W> {
23    fn array_writer<'a>(&self) -> PqArrayWriter<'a> {
24        PqArrayWriter::new(self.compression().into())
25    }
26
27    fn array_write<A: ArrayType>(&mut self, writer: PqArrayWriter) -> Result<Array<A>, Error> {
28        let f = self.builder.open(FileType::Parquet)?;
29        let name = f.name().to_owned();
30        let length = writer.write(f)?;
31        Ok(Array::new(name, length))
32    }
33
34    pub fn array_scalars<I, T>(&mut self, data: I) -> Result<Array<array_type::Scalar>, Error>
38    where
39        I: IntoIterator<Item = T>,
40        T: FloatType,
41    {
42        let mut min = MinimumScalar::new();
43        let mut writer = self.array_writer();
44        writer.add("scalar", data.into_iter().map(|v| min.visit(v)))?;
45        Ok(self.array_write(writer)?.add_write_checks(min.get()))
46    }
47
48    pub fn array_vertices<I, T>(&mut self, data: I) -> Result<Array<array_type::Vertex>, Error>
50    where
51        I: IntoIterator<Item = [T; 3]>,
52        T: FloatType,
53    {
54        let mut writer = self.array_writer();
55        writer.add_multiple(&["x", "y", "z"], data)?;
56        self.array_write(writer)
57    }
58
59    pub fn array_segments<I>(&mut self, data: I) -> Result<Array<array_type::Segment>, Error>
64    where
65        I: IntoIterator<Item = [u32; 2]>,
66    {
67        let mut max = MaximumIndex::new();
68        let mut writer = self.array_writer();
69        writer.add_multiple(&["a", "b"], data.into_iter().map(|v| max.visit_array(v)))?;
70        Ok(self.array_write(writer)?.add_write_checks(max.get()))
71    }
72
73    pub fn array_triangles<I>(&mut self, data: I) -> Result<Array<array_type::Triangle>, Error>
78    where
79        I: IntoIterator<Item = [u32; 3]>,
80    {
81        let mut max = MaximumIndex::new();
82        let mut writer = self.array_writer();
83        writer.add_multiple(
84            &["a", "b", "c"],
85            data.into_iter().map(|v| max.visit_array(v)),
86        )?;
87        Ok(self.array_write(writer)?.add_write_checks(max.get()))
88    }
89
90    pub fn array_names<I>(&mut self, data: I) -> Result<Array<array_type::Name>, Error>
92    where
93        I: IntoIterator<Item = String>,
94    {
95        let mut writer = self.array_writer();
96        writer.add("name", data)?;
97        self.array_write(writer)
98    }
99
100    pub fn array_gradient<I>(&mut self, data: I) -> Result<Array<array_type::Gradient>, Error>
104    where
105        I: IntoIterator<Item = [u8; 4]>,
106    {
107        let mut writer = self.array_writer();
108        writer.add_multiple(&["r", "g", "b", "a"], data.into_iter())?;
109        self.array_write(writer)
110    }
111
112    pub fn array_texcoords<I, T>(&mut self, data: I) -> Result<Array<array_type::Texcoord>, Error>
116    where
117        I: IntoIterator<Item = [T; 2]>,
118        T: FloatType,
119    {
120        let mut writer = self.array_writer();
121        writer.add_multiple(&["u", "v"], data)?;
122        self.array_write(writer)
123    }
124
125    pub fn array_boundaries<I, T>(&mut self, data: I) -> Result<Array<array_type::Boundary>, Error>
129    where
130        I: IntoIterator<Item = Boundary<T>>,
131        T: NumberType,
132    {
133        let mut increasing = IncreasingBoundary::new();
134        let mut writer = self.array_writer();
135        writer.add_multiple(
136            &["value", "inclusive"],
137            data.into_iter()
138                .map(|b| (increasing.visit(b.value()), b.is_inclusive())),
139        )?;
140        Ok(self.array_write(writer)?.add_write_checks(increasing.get()))
141    }
142
143    pub fn array_regular_subblocks<I>(
155        &mut self,
156        data: I,
157    ) -> Result<Array<array_type::RegularSubblock>, Error>
158    where
159        I: IntoIterator<Item = ([u32; 3], [u32; 6])>,
160    {
161        let mut parents = ParentIndices::new();
162        let mut corners = RegularCorners::new();
163        let mut writer = self.array_writer();
164        writer.add_multiple(
165            &[
166                "parent_u",
167                "parent_v",
168                "parent_w",
169                "corner_min_u",
170                "corner_min_v",
171                "corner_min_w",
172                "corner_max_u",
173                "corner_max_v",
174                "corner_max_w",
175            ],
176            data.into_iter().map(|(p, c)| {
177                parents.visit(p);
178                corners.visit(c);
179                (p[0], p[1], p[2], c[0], c[1], c[2], c[3], c[4], c[5])
180            }),
181        )?;
182        Ok(self
183            .array_write(writer)?
184            .add_write_checks(parents.get())
185            .add_write_checks(corners.get()))
186    }
187
188    pub fn array_freeform_subblocks<I, C>(
199        &mut self,
200        data: I,
201    ) -> Result<Array<array_type::FreeformSubblock>, Error>
202    where
203        I: IntoIterator<Item = ([u32; 3], [C; 6])>,
204        C: FloatType,
205    {
206        let mut corner = FreeformCorners::new();
207        let mut parent = ParentIndices::new();
208        let mut writer = self.array_writer();
209        writer.add_multiple(
210            &[
211                "parent_u",
212                "parent_v",
213                "parent_w",
214                "corner_min_u",
215                "corner_min_v",
216                "corner_min_w",
217                "corner_max_u",
218                "corner_max_v",
219                "corner_max_w",
220            ],
221            data.into_iter().map(|(p, c)| {
222                parent.visit(p);
223                corner.visit(c);
224                (p[0], p[1], p[2], c[0], c[1], c[2], c[3], c[4], c[5])
225            }),
226        )?;
227        Ok(self
228            .array_write(writer)?
229            .add_write_checks(parent.get())
230            .add_write_checks(corner.get()))
231    }
232
233    pub fn array_numbers<I, T>(&mut self, data: I) -> Result<Array<array_type::Number>, Error>
239    where
240        I: IntoIterator<Item = Option<T>>,
241        T: NumberType,
242    {
243        let mut writer = self.array_writer();
244        writer.add_nullable("number", data)?;
245        self.array_write(writer)
246    }
247
248    pub fn array_indices<I>(&mut self, data: I) -> Result<Array<array_type::Index>, Error>
254    where
255        I: IntoIterator<Item = Option<u32>>,
256    {
257        let mut max = MaximumIndex::new();
258        let mut writer = self.array_writer();
259        writer.add_nullable("index", data.into_iter().map(|v| max.visit_opt(v)))?;
260        Ok(self.array_write(writer)?.add_write_checks(max.get()))
261    }
262
263    pub fn array_vectors<I, T, V>(&mut self, data: I) -> Result<Array<array_type::Vector>, Error>
267    where
268        I: IntoIterator<Item = Option<V>>,
269        V: VectorSource<T>,
270        T: FloatType,
271    {
272        let mut writer = self.array_writer();
273        if V::IS_3D {
274            writer.add_nullable_group(
275                "vector",
276                &["x", "y", "z"],
277                data.into_iter().map(|o| o.map(V::into_3d)),
278            )?;
279        } else {
280            writer.add_nullable_group(
281                "vector",
282                &["x", "y"],
283                data.into_iter().map(|o| o.map(V::into_2d)),
284            )?;
285        }
286        self.array_write(writer)
287    }
288
289    pub fn array_text<I>(&mut self, data: I) -> Result<Array<array_type::Text>, Error>
291    where
292        I: IntoIterator<Item = Option<String>>,
293    {
294        let mut writer = self.array_writer();
295        writer.add_nullable("text", data)?;
296        self.array_write(writer)
297    }
298
299    pub fn array_booleans<I>(&mut self, data: I) -> Result<Array<array_type::Boolean>, Error>
301    where
302        I: IntoIterator<Item = Option<bool>>,
303    {
304        let mut writer = self.array_writer();
305        writer.add_nullable("bool", data)?;
306        self.array_write(writer)
307    }
308
309    pub fn array_colors<I>(&mut self, data: I) -> Result<Array<array_type::Color>, Error>
313    where
314        I: IntoIterator<Item = Option<[u8; 4]>>,
315    {
316        let mut writer = self.array_writer();
317        writer.add_nullable_group("color", &["r", "g", "b", "a"], data.into_iter())?;
318        self.array_write(writer)
319    }
320}