use arrow_schema::DataType;
use crate::arrow_enable_vec_for_type;
use crate::deserialize::ArrowDeserialize;
use crate::field::ArrowField;
use crate::serialize::ArrowSerialize;
use arrow_schema::Field;
use crate::deserialize::arrow_deserialize_vec_helper;
use arrow_array::builder::{BooleanBuilder, Float32Builder, Float64Builder};
use arrow_array::ArrayRef;
use arrow_array::{builder::FixedSizeListBuilder, FixedSizeListArray};
use std::sync::Arc;
macro_rules! impl_glam_ty {
($type:ty, $size:expr, $dt:ident, $arrow_dt:expr, $array_builder:ident, $se:expr, $de:expr) => {
impl ArrowField for $type {
type Type = Self;
fn data_type() -> DataType {
let field = Field::new("scalar", $arrow_dt, false);
DataType::FixedSizeList(Arc::new(field), $size)
}
}
arrow_enable_vec_for_type!($type);
impl ArrowSerialize for $type {
type ArrayBuilderType = FixedSizeListBuilder<$array_builder>;
fn new_array() -> Self::ArrayBuilderType {
let field = Field::new("scalar", $arrow_dt, false);
Self::ArrayBuilderType::new(<$dt as ArrowSerialize>::new_array(), $size).with_field(field)
}
fn arrow_serialize(
v: &Self::Type,
array: &mut Self::ArrayBuilderType,
) -> Result<(), arrow_schema::ArrowError> {
let v = $se(v);
array.values().append_slice(v.as_ref());
array.append(true);
Ok(())
}
}
impl ArrowDeserialize for $type {
type ArrayType = FixedSizeListArray;
fn arrow_deserialize(v: Option<ArrayRef>) -> Option<Self> {
let v = arrow_deserialize_vec_helper::<$dt>(v)?;
Some($de(v))
}
}
};
}
macro_rules! impl_glam_vec_bool {
($type:ty, $size:expr) => {
impl_glam_ty!(
$type,
$size,
bool,
DataType::Boolean,
BooleanBuilder,
|v: &$type| <[bool; $size]>::from(*v),
|v: Vec<bool>| {
let length = v.len();
match <[bool; $size]>::try_from(v).ok() {
None => panic!(
"Expected size of {} deserializing array of type `{}`, got {}",
std::any::type_name::<$type>(),
$size,
length
),
Some(array) => Self::from_array(array),
}
}
);
};
}
macro_rules! impl_glam_vec_f32 {
($type:ty, $size:expr) => {
impl_glam_ty!(
$type,
$size,
f32,
DataType::Float32,
Float32Builder,
|v: &$type| *v,
|v: Vec<f32>| Self::from_slice(&v)
);
};
}
macro_rules! impl_glam_mat_f32 {
($type:ty, $size:expr) => {
impl_glam_ty!(
$type,
$size,
f32,
DataType::Float32,
Float32Builder,
|v: &$type| *v,
|v: Vec<f32>| Self::from_cols_slice(&v)
);
};
}
macro_rules! impl_glam_vec_f64 {
($type:ty, $size:expr) => {
impl_glam_ty!(
$type,
$size,
f64,
DataType::Float64,
Float64Builder,
|v: &$type| *v,
|v: Vec<f64>| Self::from_slice(&v)
);
};
}
macro_rules! impl_glam_mat_f64 {
($type:ty, $size:expr) => {
impl_glam_ty!(
$type,
$size,
f64,
DataType::Float64,
Float64Builder,
|v: &$type| *v,
|v: Vec<f64>| Self::from_cols_slice(&v)
);
};
}
impl_glam_vec_bool!(glam::BVec2, 2);
impl_glam_vec_bool!(glam::BVec3, 3);
impl_glam_vec_bool!(glam::BVec4, 4);
impl_glam_vec_f32!(glam::Vec2, 2);
impl_glam_vec_f32!(glam::Vec3, 3);
impl_glam_vec_f32!(glam::Vec4, 4);
impl_glam_mat_f32!(glam::Mat2, 4);
impl_glam_mat_f32!(glam::Mat3, 9);
impl_glam_mat_f32!(glam::Mat4, 16);
impl_glam_vec_f64!(glam::DVec2, 2);
impl_glam_vec_f64!(glam::DVec3, 3);
impl_glam_vec_f64!(glam::DVec4, 4);
impl_glam_mat_f64!(glam::DMat2, 4);
impl_glam_mat_f64!(glam::DMat3, 9);
impl_glam_mat_f64!(glam::DMat4, 16);