vortex_array/arrays/struct_/compute/
cast.rs

1use 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());