use crate::{
array_type,
data::*,
error::{Error, InvalidData},
file::SubFile,
pqarray::PqArrayReader,
Array, ArrayType,
};
use super::{super::Reader, schemas};
impl Reader {
fn array_reader(&self, array: &Array<impl ArrayType>) -> Result<PqArrayReader<SubFile>, Error> {
let f = self.array_bytes_reader(array)?;
let reader = PqArrayReader::new(f)?;
if array.item_count() != reader.len() {
Err(InvalidData::LengthMismatch {
found: array.item_count(),
expected: reader.len(),
}
.into())
} else {
Ok(reader)
}
}
pub fn array_scalars(&self, array: &Array<array_type::Scalar>) -> Result<Scalars, Error> {
let reader = self.array_reader(array)?;
Ok(match schemas::Scalar::check(&reader)? {
schemas::Scalar::F32 => {
let inner = reader.iter_column::<f32>("scalar")?;
Scalars::F32(GenericScalars::new(inner, array.constraint()))
}
schemas::Scalar::F64 => {
let inner = reader.iter_column::<f64>("scalar")?;
Scalars::F64(GenericScalars::new(inner, array.constraint()))
}
})
}
pub fn array_vertices(&self, array: &Array<array_type::Vertex>) -> Result<Vertices, Error> {
let reader = self.array_reader(array)?;
Ok(match schemas::Vertex::check(&reader)? {
schemas::Vertex::F32 => {
Vertices::F32(GenericArrays(reader.iter_multi_column(["x", "y", "z"])?))
}
schemas::Vertex::F64 => {
Vertices::F64(GenericArrays(reader.iter_multi_column(["x", "y", "z"])?))
}
})
}
pub fn array_segments(
&self,
array: &Array<array_type::Segment>,
) -> Result<GenericPrimitives<2>, Error> {
let reader = self.array_reader(array)?;
Ok(match schemas::Segment::check(&reader)? {
schemas::Segment::U32 => {
GenericPrimitives::new(reader.iter_multi_column(["a", "b"])?, array.constraint())
}
})
}
pub fn array_triangles(
&self,
array: &Array<array_type::Triangle>,
) -> Result<GenericPrimitives<3>, Error> {
let reader = self.array_reader(array)?;
Ok(match schemas::Triangle::check(&reader)? {
schemas::Triangle::U32 => GenericPrimitives::new(
reader.iter_multi_column(["a", "b", "c"])?,
array.constraint(),
),
})
}
pub fn array_names(&self, array: &Array<array_type::Name>) -> Result<Names, Error> {
let reader = self.array_reader(array)?;
schemas::Name::check(&reader)?;
reader.iter_column("name").map(Names)
}
pub fn array_gradient(&self, array: &Array<array_type::Gradient>) -> Result<Gradient, Error> {
let reader = self.array_reader(array)?;
Ok(match schemas::Gradient::check(&reader)? {
schemas::Gradient::Rgba8 => Gradient(reader.iter_multi_column(["r", "g", "b", "a"])?),
})
}
pub fn array_texcoords(&self, array: &Array<array_type::Texcoord>) -> Result<Texcoords, Error> {
let reader = self.array_reader(array)?;
Ok(match schemas::Texcoord::check(&reader)? {
schemas::Texcoord::F32 => {
Texcoords::F32(GenericArrays(reader.iter_multi_column(["u", "v"])?))
}
schemas::Texcoord::F64 => {
Texcoords::F64(GenericArrays(reader.iter_multi_column(["u", "v"])?))
}
})
}
pub fn array_boundaries(
&self,
array: &Array<array_type::Boundary>,
) -> Result<Boundaries, Error> {
let reader = self.array_reader(array)?;
let m = schemas::Boundary::check(&reader)?;
let inclusive = reader.iter_column("inclusive")?;
Ok(match m {
schemas::Boundary::F32 => Boundaries::F32(GenericBoundaries::new(
reader.iter_column("value")?,
inclusive,
)),
schemas::Boundary::F64 => Boundaries::F64(GenericBoundaries::new(
reader.iter_column("value")?,
inclusive,
)),
schemas::Boundary::I64 => Boundaries::I64(GenericBoundaries::new(
reader.iter_column("value")?,
inclusive,
)),
schemas::Boundary::Date => Boundaries::Date(GenericBoundaries::new(
reader.iter_column("value")?,
inclusive,
)),
schemas::Boundary::DateTime => Boundaries::DateTime(GenericBoundaries::new(
reader.iter_column("value")?,
inclusive,
)),
})
}
pub fn array_regular_subblocks(
&self,
array: &Array<array_type::RegularSubblock>,
) -> Result<RegularSubblocks, Error> {
let reader = self.array_reader(array)?;
schemas::RegularSubblock::check(&reader)?;
let parents = reader.iter_multi_column(["parent_u", "parent_v", "parent_w"])?;
let corners = reader.iter_multi_column([
"corner_min_u",
"corner_min_v",
"corner_min_w",
"corner_max_u",
"corner_max_v",
"corner_max_w",
])?;
Ok(RegularSubblocks::new(parents, corners, array.constraint()))
}
pub fn array_freeform_subblocks(
&self,
array: &Array<array_type::FreeformSubblock>,
) -> Result<FreeformSubblocks, Error> {
let reader = self.array_reader(array)?;
let m = schemas::FreeformSubblock::check(&reader)?;
let parents = reader.iter_multi_column(["parent_u", "parent_v", "parent_w"])?;
Ok(match m {
schemas::FreeformSubblock::U32F32 => {
FreeformSubblocks::F32(GenericFreeformSubblocks::new(
parents,
reader.iter_multi_column([
"corner_min_u",
"corner_min_v",
"corner_min_w",
"corner_max_u",
"corner_max_v",
"corner_max_w",
])?,
array.constraint(),
))
}
schemas::FreeformSubblock::U32F64 => {
FreeformSubblocks::F64(GenericFreeformSubblocks::new(
parents,
reader.iter_multi_column([
"corner_min_u",
"corner_min_v",
"corner_min_w",
"corner_max_u",
"corner_max_v",
"corner_max_w",
])?,
array.constraint(),
))
}
})
}
pub fn array_numbers(&self, array: &Array<array_type::Number>) -> Result<Numbers, Error> {
let reader = self.array_reader(array)?;
Ok(match schemas::Number::check(&reader)? {
schemas::Number::F32 => {
Numbers::F32(GenericNumbers(reader.iter_nullable_column("number")?))
}
schemas::Number::F64 => {
Numbers::F64(GenericNumbers(reader.iter_nullable_column("number")?))
}
schemas::Number::I64 => {
Numbers::I64(GenericNumbers(reader.iter_nullable_column("number")?))
}
schemas::Number::Date => {
Numbers::Date(GenericNumbers(reader.iter_nullable_column("number")?))
}
schemas::Number::DateTime => {
Numbers::DateTime(GenericNumbers(reader.iter_nullable_column("number")?))
}
})
}
pub fn array_indices(&self, array: &Array<array_type::Index>) -> Result<Indices, Error> {
let reader = self.array_reader(array)?;
Ok(match schemas::Index::check(&reader)? {
schemas::Index::U32 => {
Indices::new(reader.iter_nullable_column("index")?, array.constraint())
}
})
}
pub fn array_vectors(&self, array: &Array<array_type::Vector>) -> Result<Vectors, Error> {
let reader = self.array_reader(array)?;
Ok(match schemas::Vector::check(&reader)? {
schemas::Vector::F32x2 => Vectors::F32x2(GenericOptionalArrays(
reader.iter_nullable_group_column("vector", ["x", "y"])?,
)),
schemas::Vector::F64x2 => Vectors::F64x2(GenericOptionalArrays(
reader.iter_nullable_group_column("vector", ["x", "y"])?,
)),
schemas::Vector::F32x3 => Vectors::F32x3(GenericOptionalArrays(
reader.iter_nullable_group_column("vector", ["x", "y", "z"])?,
)),
schemas::Vector::F64x3 => Vectors::F64x3(GenericOptionalArrays(
reader.iter_nullable_group_column("vector", ["x", "y", "z"])?,
)),
})
}
pub fn array_text(&self, array: &Array<array_type::Text>) -> Result<Text, Error> {
let reader = self.array_reader(array)?;
schemas::Text::check(&reader)?;
reader.iter_nullable_column("text").map(Text)
}
pub fn array_booleans(&self, array: &Array<array_type::Boolean>) -> Result<Booleans, Error> {
let reader = self.array_reader(array)?;
schemas::Boolean::check(&reader)?;
reader.iter_nullable_column("bool").map(Booleans)
}
pub fn array_colors(&self, array: &Array<array_type::Color>) -> Result<Colors, Error> {
let reader = self.array_reader(array)?;
Ok(match schemas::Color::check(&reader)? {
schemas::Color::Rgba8 => {
Colors(reader.iter_nullable_group_column("color", ["r", "g", "b", "a"])?)
}
})
}
}