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