vortex_array/arrays/bool/
serde.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_buffer::{Alignment, ByteBuffer};
5use vortex_dtype::DType;
6use vortex_error::{VortexResult, vortex_bail, vortex_err};
7
8use super::BoolArray;
9use crate::arrays::BoolVTable;
10use crate::serde::ArrayChildren;
11use crate::validity::Validity;
12use crate::vtable::{SerdeVTable, VTable, VisitorVTable};
13use crate::{ArrayBufferVisitor, ArrayChildVisitor, ProstMetadata};
14
15#[derive(prost::Message)]
16pub struct BoolMetadata {
17    // The offset in bits must be <8
18    #[prost(uint32, tag = "1")]
19    pub offset: u32,
20}
21
22impl SerdeVTable<BoolVTable> for BoolVTable {
23    type Metadata = ProstMetadata<BoolMetadata>;
24
25    fn metadata(array: &BoolArray) -> VortexResult<Option<Self::Metadata>> {
26        let bit_offset = array.boolean_buffer().offset();
27        let bit_offset = u32::try_from(bit_offset)
28            .map_err(|_| vortex_err!("bit_offset {bit_offset} overflows u32"))?;
29        Ok(Some(ProstMetadata(BoolMetadata { offset: bit_offset })))
30    }
31
32    fn build(
33        _encoding: &<BoolVTable as VTable>::Encoding,
34        dtype: &DType,
35        len: usize,
36        metadata: &BoolMetadata,
37        buffers: &[ByteBuffer],
38        children: &dyn ArrayChildren,
39    ) -> VortexResult<BoolArray> {
40        if buffers.len() != 1 {
41            vortex_bail!("Expected 1 buffer, got {}", buffers.len());
42        }
43
44        let validity = if children.is_empty() {
45            Validity::from(dtype.nullability())
46        } else if children.len() == 1 {
47            let validity = children.get(0, &Validity::DTYPE, len)?;
48            Validity::Array(validity)
49        } else {
50            vortex_bail!("Expected 0 or 1 child, got {}", children.len());
51        };
52
53        BoolArray::try_new(buffers[0].clone(), metadata.offset as usize, len, validity)
54    }
55}
56
57impl VisitorVTable<BoolVTable> for BoolVTable {
58    fn visit_buffers(array: &BoolArray, visitor: &mut dyn ArrayBufferVisitor) {
59        visitor.visit_buffer(&ByteBuffer::from_arrow_buffer(
60            array.boolean_buffer().clone().into_inner(),
61            Alignment::none(),
62        ))
63    }
64
65    fn visit_children(array: &BoolArray, visitor: &mut dyn ArrayChildVisitor) {
66        visitor.visit_validity(&array.validity, array.len());
67    }
68}