vortex_array/arrays/struct_/vtable/
operations.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use std::ops::Range;
5
6use itertools::Itertools;
7use vortex_scalar::Scalar;
8
9use crate::arrays::struct_::{StructArray, StructVTable};
10use crate::vtable::{OperationsVTable, ValidityHelper};
11use crate::{ArrayRef, IntoArray};
12
13impl OperationsVTable<StructVTable> for StructVTable {
14    fn slice(array: &StructArray, range: Range<usize>) -> ArrayRef {
15        let fields = array
16            .fields()
17            .iter()
18            .map(|field| field.slice(range.clone()))
19            .collect_vec();
20        // SAFETY: All invariants are preserved:
21        // - fields.len() == dtype.names().len() (same struct fields)
22        // - Every field has length == range.len() (all sliced to same range)
23        // - Each field's dtype matches the struct dtype (unchanged from original)
24        // - Validity length matches array length (both sliced to same range)
25        unsafe {
26            StructArray::new_unchecked(
27                fields,
28                array.struct_fields().clone(),
29                range.len(),
30                array.validity().slice(range),
31            )
32        }
33        .into_array()
34    }
35
36    fn scalar_at(array: &StructArray, index: usize) -> Scalar {
37        Scalar::struct_(
38            array.dtype().clone(),
39            array
40                .fields()
41                .iter()
42                .map(|field| field.scalar_at(index))
43                .collect_vec(),
44        )
45    }
46}