1use crate::{
2 Array, ArrayType, array_type,
3 data::*,
4 error::{Error, InvalidData},
5 file::{ReadAt, SubFile},
6 pqarray::PqArrayReader,
7};
8
9use super::{super::Reader, schemas};
10
11impl<R: ReadAt> Reader<R> {
12 fn array_reader(
13 &self,
14 array: &Array<impl ArrayType>,
15 ) -> Result<PqArrayReader<SubFile<R>>, Error> {
16 let f = self.array_bytes_reader(array)?;
17 let reader = PqArrayReader::new(f)?;
18 if array.item_count() != reader.len() {
19 Err(InvalidData::LengthMismatch {
20 found: array.item_count(),
21 expected: reader.len(),
22 }
23 .into())
24 } else {
25 Ok(reader)
26 }
27 }
28
29 pub fn array_scalars(&self, array: &Array<array_type::Scalar>) -> Result<Scalars<R>, Error> {
31 let reader = self.array_reader(array)?;
32 Ok(match schemas::Scalar::check(&reader)? {
33 schemas::Scalar::F32 => {
34 let inner = reader.iter_column::<f32>("scalar")?;
35 Scalars::F32(GenericScalars::new(inner, array.constraint()))
36 }
37 schemas::Scalar::F64 => {
38 let inner = reader.iter_column::<f64>("scalar")?;
39 Scalars::F64(GenericScalars::new(inner, array.constraint()))
40 }
41 })
42 }
43
44 pub fn array_vertices(&self, array: &Array<array_type::Vertex>) -> Result<Vertices<R>, Error> {
46 let reader = self.array_reader(array)?;
47 Ok(match schemas::Vertex::check(&reader)? {
48 schemas::Vertex::F32 => {
49 Vertices::F32(GenericArrays(reader.iter_multi_column(["x", "y", "z"])?))
50 }
51 schemas::Vertex::F64 => {
52 Vertices::F64(GenericArrays(reader.iter_multi_column(["x", "y", "z"])?))
53 }
54 })
55 }
56
57 pub fn array_segments(
59 &self,
60 array: &Array<array_type::Segment>,
61 ) -> Result<GenericPrimitives<2, R>, Error> {
62 let reader = self.array_reader(array)?;
63 Ok(match schemas::Segment::check(&reader)? {
64 schemas::Segment::U32 => {
65 GenericPrimitives::new(reader.iter_multi_column(["a", "b"])?, array.constraint())
66 }
67 })
68 }
69
70 pub fn array_triangles(
72 &self,
73 array: &Array<array_type::Triangle>,
74 ) -> Result<GenericPrimitives<3, R>, Error> {
75 let reader = self.array_reader(array)?;
76 Ok(match schemas::Triangle::check(&reader)? {
77 schemas::Triangle::U32 => GenericPrimitives::new(
78 reader.iter_multi_column(["a", "b", "c"])?,
79 array.constraint(),
80 ),
81 })
82 }
83
84 pub fn array_names(&self, array: &Array<array_type::Name>) -> Result<Names<R>, Error> {
86 let reader = self.array_reader(array)?;
87 schemas::Name::check(&reader)?;
88 reader.iter_column("name").map(Names)
89 }
90
91 pub fn array_gradient(
93 &self,
94 array: &Array<array_type::Gradient>,
95 ) -> Result<Gradient<R>, Error> {
96 let reader = self.array_reader(array)?;
97 Ok(match schemas::Gradient::check(&reader)? {
98 schemas::Gradient::Rgba8 => Gradient(reader.iter_multi_column(["r", "g", "b", "a"])?),
99 })
100 }
101
102 pub fn array_texcoords(
104 &self,
105 array: &Array<array_type::Texcoord>,
106 ) -> Result<Texcoords<R>, Error> {
107 let reader = self.array_reader(array)?;
108 Ok(match schemas::Texcoord::check(&reader)? {
109 schemas::Texcoord::F32 => {
110 Texcoords::F32(GenericArrays(reader.iter_multi_column(["u", "v"])?))
111 }
112 schemas::Texcoord::F64 => {
113 Texcoords::F64(GenericArrays(reader.iter_multi_column(["u", "v"])?))
114 }
115 })
116 }
117
118 pub fn array_boundaries(
120 &self,
121 array: &Array<array_type::Boundary>,
122 ) -> Result<Boundaries<R>, Error> {
123 let reader = self.array_reader(array)?;
124 let m = schemas::Boundary::check(&reader)?;
125 let inclusive = reader.iter_column("inclusive")?;
126 Ok(match m {
127 schemas::Boundary::F32 => Boundaries::F32(GenericBoundaries::new(
128 reader.iter_column("value")?,
129 inclusive,
130 )),
131 schemas::Boundary::F64 => Boundaries::F64(GenericBoundaries::new(
132 reader.iter_column("value")?,
133 inclusive,
134 )),
135 schemas::Boundary::I64 => Boundaries::I64(GenericBoundaries::new(
136 reader.iter_column("value")?,
137 inclusive,
138 )),
139 schemas::Boundary::Date => Boundaries::Date(GenericBoundaries::new(
140 reader.iter_column("value")?,
141 inclusive,
142 )),
143 schemas::Boundary::DateTime => Boundaries::DateTime(GenericBoundaries::new(
144 reader.iter_column("value")?,
145 inclusive,
146 )),
147 })
148 }
149
150 pub fn array_regular_subblocks(
152 &self,
153 array: &Array<array_type::RegularSubblock>,
154 ) -> Result<RegularSubblocks<R>, Error> {
155 let reader = self.array_reader(array)?;
156 schemas::RegularSubblock::check(&reader)?;
157 let parents = reader.iter_multi_column(["parent_u", "parent_v", "parent_w"])?;
158 let corners = reader.iter_multi_column([
159 "corner_min_u",
160 "corner_min_v",
161 "corner_min_w",
162 "corner_max_u",
163 "corner_max_v",
164 "corner_max_w",
165 ])?;
166 Ok(RegularSubblocks::new(parents, corners, array.constraint()))
167 }
168
169 pub fn array_freeform_subblocks(
171 &self,
172 array: &Array<array_type::FreeformSubblock>,
173 ) -> Result<FreeformSubblocks<R>, Error> {
174 let reader = self.array_reader(array)?;
175 let m = schemas::FreeformSubblock::check(&reader)?;
176 let parents = reader.iter_multi_column(["parent_u", "parent_v", "parent_w"])?;
177 Ok(match m {
178 schemas::FreeformSubblock::U32F32 => {
179 FreeformSubblocks::F32(GenericFreeformSubblocks::new(
180 parents,
181 reader.iter_multi_column([
182 "corner_min_u",
183 "corner_min_v",
184 "corner_min_w",
185 "corner_max_u",
186 "corner_max_v",
187 "corner_max_w",
188 ])?,
189 array.constraint(),
190 ))
191 }
192 schemas::FreeformSubblock::U32F64 => {
193 FreeformSubblocks::F64(GenericFreeformSubblocks::new(
194 parents,
195 reader.iter_multi_column([
196 "corner_min_u",
197 "corner_min_v",
198 "corner_min_w",
199 "corner_max_u",
200 "corner_max_v",
201 "corner_max_w",
202 ])?,
203 array.constraint(),
204 ))
205 }
206 })
207 }
208
209 pub fn array_numbers(&self, array: &Array<array_type::Number>) -> Result<Numbers<R>, Error> {
211 let reader = self.array_reader(array)?;
212 Ok(match schemas::Number::check(&reader)? {
213 schemas::Number::F32 => {
214 Numbers::F32(GenericNumbers(reader.iter_nullable_column("number")?))
215 }
216 schemas::Number::F64 => {
217 Numbers::F64(GenericNumbers(reader.iter_nullable_column("number")?))
218 }
219 schemas::Number::I64 => {
220 Numbers::I64(GenericNumbers(reader.iter_nullable_column("number")?))
221 }
222 schemas::Number::Date => {
223 Numbers::Date(GenericNumbers(reader.iter_nullable_column("number")?))
224 }
225 schemas::Number::DateTime => {
226 Numbers::DateTime(GenericNumbers(reader.iter_nullable_column("number")?))
227 }
228 })
229 }
230
231 pub fn array_indices(&self, array: &Array<array_type::Index>) -> Result<Indices<R>, Error> {
233 let reader = self.array_reader(array)?;
234 Ok(match schemas::Index::check(&reader)? {
235 schemas::Index::U32 => {
236 Indices::new(reader.iter_nullable_column("index")?, array.constraint())
237 }
238 })
239 }
240
241 pub fn array_vectors(&self, array: &Array<array_type::Vector>) -> Result<Vectors<R>, Error> {
243 let reader = self.array_reader(array)?;
244 Ok(match schemas::Vector::check(&reader)? {
245 schemas::Vector::F32x2 => Vectors::F32x2(GenericOptionalArrays(
246 reader.iter_nullable_group_column("vector", ["x", "y"])?,
247 )),
248 schemas::Vector::F64x2 => Vectors::F64x2(GenericOptionalArrays(
249 reader.iter_nullable_group_column("vector", ["x", "y"])?,
250 )),
251 schemas::Vector::F32x3 => Vectors::F32x3(GenericOptionalArrays(
252 reader.iter_nullable_group_column("vector", ["x", "y", "z"])?,
253 )),
254 schemas::Vector::F64x3 => Vectors::F64x3(GenericOptionalArrays(
255 reader.iter_nullable_group_column("vector", ["x", "y", "z"])?,
256 )),
257 })
258 }
259
260 pub fn array_text(&self, array: &Array<array_type::Text>) -> Result<Text<R>, Error> {
262 let reader = self.array_reader(array)?;
263 schemas::Text::check(&reader)?;
264 reader.iter_nullable_column("text").map(Text)
265 }
266
267 pub fn array_booleans(&self, array: &Array<array_type::Boolean>) -> Result<Booleans<R>, Error> {
269 let reader = self.array_reader(array)?;
270 schemas::Boolean::check(&reader)?;
271 reader.iter_nullable_column("bool").map(Booleans)
272 }
273
274 pub fn array_colors(&self, array: &Array<array_type::Color>) -> Result<Colors<R>, Error> {
276 let reader = self.array_reader(array)?;
277 Ok(match schemas::Color::check(&reader)? {
278 schemas::Color::Rgba8 => {
279 Colors(reader.iter_nullable_group_column("color", ["r", "g", "b", "a"])?)
280 }
281 })
282 }
283}