vortex_vector/listview/
scalar.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use std::sync::Arc;
5
6use vortex_dtype::DType;
7use vortex_error::vortex_panic;
8use vortex_mask::Mask;
9use vortex_mask::MaskMut;
10
11use crate::Scalar;
12use crate::ScalarOps;
13use crate::VectorMut;
14use crate::VectorMutOps;
15use crate::VectorOps;
16use crate::listview::ListViewVector;
17use crate::listview::ListViewVectorMut;
18
19/// A scalar value for list view types.
20///
21/// The inner value is a [`ListViewVector`] with length 1.
22#[derive(Clone, Debug, PartialEq)]
23pub struct ListViewScalar(ListViewVector);
24
25impl ListViewScalar {
26    /// Create a new [`ListViewScalar`] from a length-1 [`ListViewVector`].
27    ///
28    /// # Panics
29    ///
30    /// Panics if the input vector does not have length 1.
31    pub fn new(vector: ListViewVector) -> Self {
32        assert_eq!(vector.len(), 1);
33        Self(vector)
34    }
35
36    /// Returns the inner length-1 vector representing the list view scalar.
37    pub fn value(&self) -> &ListViewVector {
38        &self.0
39    }
40}
41
42impl ListViewScalar {
43    /// Creates a zero (empty list) list view scalar of the given [`DType`].
44    ///
45    /// # Panics
46    ///
47    /// Panics if the dtype is not a [`DType::List`].
48    pub fn zero(dtype: &DType) -> Self {
49        if !matches!(dtype, DType::List(..)) {
50            vortex_panic!("Expected List dtype, got {}", dtype);
51        }
52
53        let mut vec = VectorMut::with_capacity(dtype, 1);
54        vec.append_zeros(1);
55        vec.freeze().scalar_at(0).into_list()
56    }
57
58    /// Creates a null list view scalar of the given [`DType`].
59    ///
60    /// # Panics
61    ///
62    /// Panics if the dtype is not a nullable [`DType::List`].
63    pub fn null(dtype: &DType) -> Self {
64        match dtype {
65            DType::List(_, n) if n.is_nullable() => {}
66            DType::List(..) => vortex_panic!("Expected nullable List dtype, got {}", dtype),
67            _ => vortex_panic!("Expected List dtype, got {}", dtype),
68        }
69
70        let mut vec = VectorMut::with_capacity(dtype, 1);
71        vec.append_nulls(1);
72        vec.freeze().scalar_at(0).into_list()
73    }
74}
75
76impl ScalarOps for ListViewScalar {
77    fn is_valid(&self) -> bool {
78        self.0.validity().value(0)
79    }
80
81    fn mask_validity(&mut self, mask: bool) {
82        if !mask {
83            self.0.mask_validity(&Mask::new_false(1))
84        }
85    }
86
87    fn repeat(&self, n: usize) -> VectorMut {
88        // Grab the scalar elements.
89        let elements = self.0.elements.clone();
90        // Repeat the offset and size n times.
91        let offsets = self.0.offsets.scalar_at(0).repeat(n).into_primitive();
92        let sizes = self.0.sizes.scalar_at(0).repeat(n).into_primitive();
93        unsafe {
94            ListViewVectorMut::new_unchecked(
95                Box::new(Arc::unwrap_or_clone(elements).into_mut()),
96                offsets,
97                sizes,
98                MaskMut::new(n, self.is_valid()),
99            )
100        }
101        .into()
102    }
103}
104
105impl From<ListViewScalar> for Scalar {
106    fn from(val: ListViewScalar) -> Self {
107        Scalar::List(val)
108    }
109}