Skip to main content

vortex_array/scalar/
downcast.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4//! Scalar downcasting methods to typed views.
5
6use vortex_buffer::BufferString;
7use vortex_buffer::ByteBuffer;
8use vortex_error::VortexExpect;
9use vortex_error::vortex_panic;
10
11use crate::scalar::BinaryScalar;
12use crate::scalar::BoolScalar;
13use crate::scalar::DecimalScalar;
14use crate::scalar::DecimalValue;
15use crate::scalar::ExtScalar;
16use crate::scalar::ListScalar;
17use crate::scalar::PValue;
18use crate::scalar::PrimitiveScalar;
19use crate::scalar::Scalar;
20use crate::scalar::ScalarValue;
21use crate::scalar::StructScalar;
22use crate::scalar::Utf8Scalar;
23
24impl Scalar {
25    /// Returns a view of the scalar as a boolean scalar.
26    ///
27    /// # Panics
28    ///
29    /// Panics if the scalar does not have a [`Bool`](crate::dtype::DType::Bool) type.
30    pub fn as_bool(&self) -> BoolScalar<'_> {
31        self.as_bool_opt()
32            .vortex_expect("Failed to convert scalar to bool")
33    }
34
35    /// Returns a view of the scalar as a boolean scalar if it has a boolean type.
36    pub fn as_bool_opt(&self) -> Option<BoolScalar<'_>> {
37        BoolScalar::try_new(self.dtype(), self.value()).ok()
38    }
39
40    /// Returns a view of the scalar as a primitive scalar.
41    ///
42    /// # Panics
43    ///
44    /// Panics if the scalar does not have a [`Primitive`](crate::dtype::DType::Primitive) type.
45    pub fn as_primitive(&self) -> PrimitiveScalar<'_> {
46        self.as_primitive_opt()
47            .vortex_expect("Failed to convert scalar to primitive")
48    }
49
50    /// Returns a view of the scalar as a primitive scalar if it has a primitive type.
51    pub fn as_primitive_opt(&self) -> Option<PrimitiveScalar<'_>> {
52        PrimitiveScalar::try_new(self.dtype(), self.value()).ok()
53    }
54
55    /// Returns a view of the scalar as a decimal scalar.
56    ///
57    /// # Panics
58    ///
59    /// Panics if the scalar does not have a [`Decimal`](crate::dtype::DType::Decimal) type.
60    pub fn as_decimal(&self) -> DecimalScalar<'_> {
61        self.as_decimal_opt()
62            .vortex_expect("Failed to convert scalar to decimal")
63    }
64
65    /// Returns a view of the scalar as a decimal scalar if it has a decimal type.
66    pub fn as_decimal_opt(&self) -> Option<DecimalScalar<'_>> {
67        DecimalScalar::try_new(self.dtype(), self.value()).ok()
68    }
69
70    /// Returns a view of the scalar as a UTF-8 string scalar.
71    ///
72    /// # Panics
73    ///
74    /// Panics if the scalar does not have a [`Utf8`](crate::dtype::DType::Utf8) type.
75    pub fn as_utf8(&self) -> Utf8Scalar<'_> {
76        self.as_utf8_opt()
77            .vortex_expect("Failed to convert scalar to utf8")
78    }
79
80    /// Returns a view of the scalar as a UTF-8 string scalar if it has a UTF-8 type.
81    pub fn as_utf8_opt(&self) -> Option<Utf8Scalar<'_>> {
82        Utf8Scalar::try_new(self.dtype(), self.value()).ok()
83    }
84
85    /// Returns a view of the scalar as a binary scalar.
86    ///
87    /// # Panics
88    ///
89    /// Panics if the scalar does not have a [`Binary`](crate::dtype::DType::Binary) type.
90    pub fn as_binary(&self) -> BinaryScalar<'_> {
91        self.as_binary_opt()
92            .vortex_expect("Failed to convert scalar to binary")
93    }
94
95    /// Returns a view of the scalar as a binary scalar if it has a binary type.
96    pub fn as_binary_opt(&self) -> Option<BinaryScalar<'_>> {
97        BinaryScalar::try_new(self.dtype(), self.value()).ok()
98    }
99
100    /// Returns a view of the scalar as a struct scalar.
101    ///
102    /// # Panics
103    ///
104    /// Panics if the scalar does not have a [`Struct`](crate::dtype::DType::Struct) type.
105    pub fn as_struct(&self) -> StructScalar<'_> {
106        self.as_struct_opt()
107            .vortex_expect("Failed to convert scalar to struct")
108    }
109
110    /// Returns a view of the scalar as a struct scalar if it has a struct type.
111    pub fn as_struct_opt(&self) -> Option<StructScalar<'_>> {
112        StructScalar::try_new(self.dtype(), self.value()).ok()
113    }
114
115    /// Returns a view of the scalar as a list scalar.
116    ///
117    /// Note that we use [`ListScalar`] to represent **both** [`List`](crate::dtype::DType::List) and
118    /// [`FixedSizeList`](crate::dtype::DType::FixedSizeList).
119    ///
120    /// # Panics
121    ///
122    /// Panics if the scalar does not have a [`List`](crate::dtype::DType::List) or [`FixedSizeList`](crate::dtype::DType::FixedSizeList) type.
123    pub fn as_list(&self) -> ListScalar<'_> {
124        self.as_list_opt()
125            .vortex_expect("Failed to convert scalar to list")
126    }
127
128    /// Returns a view of the scalar as a list scalar if it has a list type.
129    ///
130    /// Note that we use [`ListScalar`] to represent **both** [`List`](crate::dtype::DType::List) and
131    /// [`FixedSizeList`](crate::dtype::DType::FixedSizeList).
132    pub fn as_list_opt(&self) -> Option<ListScalar<'_>> {
133        ListScalar::try_new(self.dtype(), self.value()).ok()
134    }
135
136    /// Returns a view of the scalar as an extension scalar.
137    ///
138    /// # Panics
139    ///
140    /// Panics if the scalar does not have a [`Extension`](crate::dtype::DType::Extension) type.
141    pub fn as_extension(&self) -> ExtScalar<'_> {
142        self.as_extension_opt()
143            .vortex_expect("Failed to convert scalar to extension")
144    }
145
146    /// Returns a view of the scalar as an extension scalar if it has an extension type.
147    pub fn as_extension_opt(&self) -> Option<ExtScalar<'_>> {
148        if !self.dtype().is_extension() {
149            return None;
150        }
151
152        // SAFETY: Because we are a valid Scalar, we have already validated that the value is valid
153        // for this extension type.
154        Some(ExtScalar::new_unchecked(self.dtype(), self.value()))
155    }
156}
157
158impl ScalarValue {
159    /// Returns the boolean value, panicking if the value is not a [`Bool`][ScalarValue::Bool].
160    pub fn as_bool(&self) -> bool {
161        match self {
162            ScalarValue::Bool(b) => *b,
163            _ => vortex_panic!("ScalarValue is not a Bool"),
164        }
165    }
166
167    /// Returns the primitive value, panicking if the value is not a
168    /// [`Primitive`][ScalarValue::Primitive].
169    pub fn as_primitive(&self) -> &PValue {
170        match self {
171            ScalarValue::Primitive(p) => p,
172            _ => vortex_panic!("ScalarValue is not a Primitive"),
173        }
174    }
175
176    /// Returns the decimal value, panicking if the value is not a
177    /// [`Decimal`][ScalarValue::Decimal].
178    pub fn as_decimal(&self) -> &DecimalValue {
179        match self {
180            ScalarValue::Decimal(d) => d,
181            _ => vortex_panic!("ScalarValue is not a Decimal"),
182        }
183    }
184
185    /// Returns the UTF-8 string value, panicking if the value is not a [`Utf8`][ScalarValue::Utf8].
186    pub fn as_utf8(&self) -> &BufferString {
187        match self {
188            ScalarValue::Utf8(s) => s,
189            _ => vortex_panic!("ScalarValue is not a Utf8"),
190        }
191    }
192
193    /// Returns the binary value, panicking if the value is not a [`Binary`][ScalarValue::Binary].
194    pub fn as_binary(&self) -> &ByteBuffer {
195        match self {
196            ScalarValue::Binary(b) => b,
197            _ => vortex_panic!("ScalarValue is not a Binary"),
198        }
199    }
200
201    /// Returns the list elements, panicking if the value is not a [`List`][ScalarValue::List].
202    pub fn as_list(&self) -> &[Option<ScalarValue>] {
203        match self {
204            ScalarValue::List(elements) => elements,
205            _ => vortex_panic!("ScalarValue is not a List"),
206        }
207    }
208
209    /// Returns the boolean value, panicking if the value is not a [`Bool`][ScalarValue::Bool].
210    pub fn into_bool(self) -> bool {
211        match self {
212            ScalarValue::Bool(b) => b,
213            _ => vortex_panic!("ScalarValue is not a Bool"),
214        }
215    }
216
217    /// Returns the primitive value, panicking if the value is not a
218    /// [`Primitive`][ScalarValue::Primitive].
219    pub fn into_primitive(self) -> PValue {
220        match self {
221            ScalarValue::Primitive(p) => p,
222            _ => vortex_panic!("ScalarValue is not a Primitive"),
223        }
224    }
225
226    /// Returns the decimal value, panicking if the value is not a
227    /// [`Decimal`][ScalarValue::Decimal].
228    pub fn into_decimal(self) -> DecimalValue {
229        match self {
230            ScalarValue::Decimal(d) => d,
231            _ => vortex_panic!("ScalarValue is not a Decimal"),
232        }
233    }
234
235    /// Returns the UTF-8 string value, panicking if the value is not a [`Utf8`][ScalarValue::Utf8].
236    pub fn into_utf8(self) -> BufferString {
237        match self {
238            ScalarValue::Utf8(s) => s,
239            _ => vortex_panic!("ScalarValue is not a Utf8"),
240        }
241    }
242
243    /// Returns the binary value, panicking if the value is not a [`Binary`][ScalarValue::Binary].
244    pub fn into_binary(self) -> ByteBuffer {
245        match self {
246            ScalarValue::Binary(b) => b,
247            _ => vortex_panic!("ScalarValue is not a Binary"),
248        }
249    }
250
251    /// Returns the list elements, panicking if the value is not a [`List`][ScalarValue::List].
252    pub fn into_list(self) -> Vec<Option<ScalarValue>> {
253        match self {
254            ScalarValue::List(elements) => elements,
255            _ => vortex_panic!("ScalarValue is not a List"),
256        }
257    }
258}