vortex_vector/struct_/
scalar.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_dtype::DType;
5use vortex_error::vortex_panic;
6use vortex_mask::Mask;
7use vortex_mask::MaskMut;
8
9use crate::Scalar;
10use crate::ScalarOps;
11use crate::VectorMut;
12use crate::VectorMutOps;
13use crate::VectorOps;
14use crate::struct_::StructVector;
15use crate::struct_::StructVectorMut;
16
17/// Represents a struct scalar value.
18///
19/// The inner value is a [`StructVector`] with length 1.
20#[derive(Clone, Debug, PartialEq, Eq)]
21pub struct StructScalar(StructVector);
22
23impl StructScalar {
24    /// Creates a new [`StructScalar`] from a length-1 [`StructVector`].
25    ///
26    /// # Panics
27    ///
28    /// Panics if the input vector does not have length 1.
29    pub fn new(vector: StructVector) -> Self {
30        assert_eq!(vector.len(), 1);
31        Self(vector)
32    }
33
34    /// Returns the inner length-1 vector representing the struct scalar.
35    pub fn value(&self) -> &StructVector {
36        &self.0
37    }
38
39    /// Returns the nth field scalar of the struct.
40    pub fn field(&self, field_idx: usize) -> Scalar {
41        self.0.fields()[field_idx].scalar_at(0)
42    }
43
44    /// Returns an iterator over the field scalars of the struct.
45    pub fn fields(&self) -> impl Iterator<Item = Scalar> {
46        self.0.fields().iter().map(|f| f.scalar_at(0))
47    }
48}
49
50impl StructScalar {
51    /// Creates a zero (default fields) struct scalar of the given [`DType`].
52    ///
53    /// # Panics
54    ///
55    /// Panics if the dtype is not a [`DType::Struct`].
56    pub fn zero(dtype: &DType) -> Self {
57        if !matches!(dtype, DType::Struct(..)) {
58            vortex_panic!("Expected Struct dtype, got {}", dtype);
59        }
60
61        let mut vec = VectorMut::with_capacity(dtype, 1);
62        vec.append_zeros(1);
63        vec.freeze().scalar_at(0).into_struct()
64    }
65
66    /// Creates a null struct scalar of the given [`DType`].
67    ///
68    /// # Panics
69    ///
70    /// Panics if the dtype is not a nullable [`DType::Struct`].
71    pub fn null(dtype: &DType) -> Self {
72        match dtype {
73            DType::Struct(_, n) if n.is_nullable() => {}
74            DType::Struct(..) => vortex_panic!("Expected nullable Struct dtype, got {}", dtype),
75            _ => vortex_panic!("Expected Struct dtype, got {}", dtype),
76        }
77
78        let mut vec = VectorMut::with_capacity(dtype, 1);
79        vec.append_nulls(1);
80        vec.freeze().scalar_at(0).into_struct()
81    }
82}
83
84impl ScalarOps for StructScalar {
85    fn is_valid(&self) -> bool {
86        self.0.validity().value(0)
87    }
88
89    fn mask_validity(&mut self, mask: bool) {
90        if !mask {
91            self.0.mask_validity(&Mask::new_false(1))
92        }
93    }
94
95    fn repeat(&self, n: usize) -> VectorMut {
96        let fields = self
97            .0
98            .fields()
99            .iter()
100            .map(|f| f.scalar_at(0).repeat(n))
101            .collect();
102        let validity = MaskMut::new(n, self.is_valid());
103        VectorMut::Struct(StructVectorMut::new(fields, validity))
104    }
105}
106
107impl From<StructScalar> for Scalar {
108    fn from(val: StructScalar) -> Self {
109        Scalar::Struct(val)
110    }
111}