vortex_array/arrays/struct_/
serde.rs

1use itertools::Itertools;
2use vortex_buffer::ByteBuffer;
3use vortex_dtype::DType;
4use vortex_error::{VortexExpect, VortexResult, vortex_bail};
5
6use super::StructEncoding;
7use crate::arrays::{StructArray, StructVTable};
8use crate::serde::ArrayChildren;
9use crate::validity::Validity;
10use crate::vtable::{SerdeVTable, ValidityHelper, VisitorVTable};
11use crate::{ArrayBufferVisitor, ArrayChildVisitor, EmptyMetadata};
12
13impl SerdeVTable<StructVTable> for StructVTable {
14    type Metadata = EmptyMetadata;
15
16    fn metadata(_array: &StructArray) -> VortexResult<Option<Self::Metadata>> {
17        Ok(Some(EmptyMetadata))
18    }
19
20    fn build(
21        _encoding: &StructEncoding,
22        dtype: &DType,
23        len: usize,
24        _metadata: &Self::Metadata,
25        _buffers: &[ByteBuffer],
26        children: &dyn ArrayChildren,
27    ) -> VortexResult<StructArray> {
28        let DType::Struct(struct_dtype, nullability) = dtype else {
29            vortex_bail!("Expected struct dtype, found {:?}", dtype)
30        };
31
32        let validity = if children.len() == struct_dtype.nfields() {
33            Validity::from(*nullability)
34        } else if children.len() == struct_dtype.nfields() + 1 {
35            // Validity is the first child if it exists.
36            let validity = children.get(0, &Validity::DTYPE, len)?;
37            Validity::Array(validity)
38        } else {
39            vortex_bail!(
40                "Expected {} or {} children, found {}",
41                struct_dtype.nfields(),
42                struct_dtype.nfields() + 1,
43                children.len()
44            );
45        };
46
47        let children = (0..children.len())
48            .map(|i| {
49                let child_dtype = struct_dtype
50                    .field_by_index(i)
51                    .vortex_expect("no out of bounds");
52                children.get(i, &child_dtype, len)
53            })
54            .try_collect()?;
55
56        StructArray::try_new_with_dtype(children, struct_dtype.clone(), len, validity)
57    }
58}
59
60impl VisitorVTable<StructVTable> for StructVTable {
61    fn visit_buffers(_array: &StructArray, _visitor: &mut dyn ArrayBufferVisitor) {}
62
63    fn visit_children(array: &StructArray, visitor: &mut dyn ArrayChildVisitor) {
64        visitor.visit_validity(array.validity(), array.len());
65        for (idx, name) in array.names().iter().enumerate() {
66            visitor.visit_child(name.as_ref(), &array.fields()[idx]);
67        }
68    }
69}