vortex_array/arrays/struct_/compute/
cast.rs1use itertools::Itertools;
2use vortex_dtype::DType;
3use vortex_error::{VortexExpect, VortexResult, vortex_bail};
4
5use crate::arrays::{StructArray, StructVTable};
6use crate::compute::{CastKernel, CastKernelAdapter, cast};
7use crate::vtable::ValidityHelper;
8use crate::{ArrayRef, IntoArray, register_kernel};
9
10impl CastKernel for StructVTable {
11 fn cast(&self, array: &StructArray, dtype: &DType) -> VortexResult<ArrayRef> {
12 let Some(target_sdtype) = dtype.as_struct() else {
13 vortex_bail!("cannot cast {} to {}", array.dtype(), dtype);
14 };
15
16 let source_sdtype = array
17 .dtype()
18 .as_struct()
19 .vortex_expect("struct array must have struct dtype");
20
21 if target_sdtype.names() != source_sdtype.names() {
22 vortex_bail!("cannot cast {} to {}", array.dtype(), dtype);
23 }
24
25 let validity = array
26 .validity()
27 .clone()
28 .cast_nullability(dtype.nullability())?;
29
30 StructArray::try_new(
31 target_sdtype.names().clone(),
32 array
33 .fields()
34 .iter()
35 .zip_eq(target_sdtype.fields())
36 .map(|(field, dtype)| cast(field, &dtype))
37 .try_collect()?,
38 array.len(),
39 validity,
40 )
41 .map(|a| a.into_array())
42 }
43}
44
45register_kernel!(CastKernelAdapter(StructVTable).lift());