vortex_array/arrays/struct_/vtable/
serde.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use itertools::Itertools;
5use vortex_buffer::ByteBuffer;
6use vortex_dtype::DType;
7use vortex_error::{VortexExpect, VortexResult, vortex_bail};
8
9use crate::EmptyMetadata;
10use crate::arrays::struct_::{StructArray, StructEncoding, StructVTable};
11use crate::serde::ArrayChildren;
12use crate::validity::Validity;
13use crate::vtable::SerdeVTable;
14
15impl SerdeVTable<StructVTable> for StructVTable {
16    type Metadata = EmptyMetadata;
17
18    fn metadata(_array: &StructArray) -> VortexResult<Option<Self::Metadata>> {
19        Ok(Some(EmptyMetadata))
20    }
21
22    fn build(
23        _encoding: &StructEncoding,
24        dtype: &DType,
25        len: usize,
26        _metadata: &Self::Metadata,
27        _buffers: &[ByteBuffer],
28        children: &dyn ArrayChildren,
29    ) -> VortexResult<StructArray> {
30        let DType::Struct(struct_dtype, nullability) = dtype else {
31            vortex_bail!("Expected struct dtype, found {:?}", dtype)
32        };
33
34        let (validity, non_data_children) = if children.len() == struct_dtype.nfields() {
35            (Validity::from(*nullability), 0_usize)
36        } else if children.len() == struct_dtype.nfields() + 1 {
37            // Validity is the first child if it exists.
38            let validity = children.get(0, &Validity::DTYPE, len)?;
39            (Validity::Array(validity), 1_usize)
40        } else {
41            vortex_bail!(
42                "Expected {} or {} children, found {}",
43                struct_dtype.nfields(),
44                struct_dtype.nfields() + 1,
45                children.len()
46            );
47        };
48
49        let children: Vec<_> = (0..struct_dtype.nfields())
50            .map(|i| {
51                let child_dtype = struct_dtype
52                    .field_by_index(i)
53                    .vortex_expect("no out of bounds");
54                children.get(non_data_children + i, &child_dtype, len)
55            })
56            .try_collect()?;
57
58        StructArray::try_new_with_dtype(children, struct_dtype.clone(), len, validity)
59    }
60}