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`](vortex_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`](vortex_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`](vortex_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`](vortex_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`](vortex_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`](vortex_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`](vortex_dtype::DType::List) and
118 /// [`FixedSizeList`](vortex_dtype::DType::FixedSizeList).
119 ///
120 /// # Panics
121 ///
122 /// Panics if the scalar does not have a [`List`](vortex_dtype::DType::List) or [`FixedSizeList`](vortex_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`](vortex_dtype::DType::List) and
131 /// [`FixedSizeList`](vortex_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`](vortex_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 ExtScalar::try_new(self.dtype(), self.value()).ok()
149 }
150}
151
152impl ScalarValue {
153 /// Returns the boolean value, panicking if the value is not a [`Bool`][ScalarValue::Bool].
154 pub fn as_bool(&self) -> bool {
155 match self {
156 ScalarValue::Bool(b) => *b,
157 _ => vortex_panic!("ScalarValue is not a Bool"),
158 }
159 }
160
161 /// Returns the primitive value, panicking if the value is not a
162 /// [`Primitive`][ScalarValue::Primitive].
163 pub fn as_primitive(&self) -> &PValue {
164 match self {
165 ScalarValue::Primitive(p) => p,
166 _ => vortex_panic!("ScalarValue is not a Primitive"),
167 }
168 }
169
170 /// Returns the decimal value, panicking if the value is not a
171 /// [`Decimal`][ScalarValue::Decimal].
172 pub fn as_decimal(&self) -> &DecimalValue {
173 match self {
174 ScalarValue::Decimal(d) => d,
175 _ => vortex_panic!("ScalarValue is not a Decimal"),
176 }
177 }
178
179 /// Returns the UTF-8 string value, panicking if the value is not a [`Utf8`][ScalarValue::Utf8].
180 pub fn as_utf8(&self) -> &BufferString {
181 match self {
182 ScalarValue::Utf8(s) => s,
183 _ => vortex_panic!("ScalarValue is not a Utf8"),
184 }
185 }
186
187 /// Returns the binary value, panicking if the value is not a [`Binary`][ScalarValue::Binary].
188 pub fn as_binary(&self) -> &ByteBuffer {
189 match self {
190 ScalarValue::Binary(b) => b,
191 _ => vortex_panic!("ScalarValue is not a Binary"),
192 }
193 }
194
195 /// Returns the list elements, panicking if the value is not a [`List`][ScalarValue::List].
196 pub fn as_list(&self) -> &[Option<ScalarValue>] {
197 match self {
198 ScalarValue::List(elements) => elements,
199 _ => vortex_panic!("ScalarValue is not a List"),
200 }
201 }
202
203 /// Returns the boolean value, panicking if the value is not a [`Bool`][ScalarValue::Bool].
204 pub fn into_bool(self) -> bool {
205 match self {
206 ScalarValue::Bool(b) => b,
207 _ => vortex_panic!("ScalarValue is not a Bool"),
208 }
209 }
210
211 /// Returns the primitive value, panicking if the value is not a
212 /// [`Primitive`][ScalarValue::Primitive].
213 pub fn into_primitive(self) -> PValue {
214 match self {
215 ScalarValue::Primitive(p) => p,
216 _ => vortex_panic!("ScalarValue is not a Primitive"),
217 }
218 }
219
220 /// Returns the decimal value, panicking if the value is not a
221 /// [`Decimal`][ScalarValue::Decimal].
222 pub fn into_decimal(self) -> DecimalValue {
223 match self {
224 ScalarValue::Decimal(d) => d,
225 _ => vortex_panic!("ScalarValue is not a Decimal"),
226 }
227 }
228
229 /// Returns the UTF-8 string value, panicking if the value is not a [`Utf8`][ScalarValue::Utf8].
230 pub fn into_utf8(self) -> BufferString {
231 match self {
232 ScalarValue::Utf8(s) => s,
233 _ => vortex_panic!("ScalarValue is not a Utf8"),
234 }
235 }
236
237 /// Returns the binary value, panicking if the value is not a [`Binary`][ScalarValue::Binary].
238 pub fn into_binary(self) -> ByteBuffer {
239 match self {
240 ScalarValue::Binary(b) => b,
241 _ => vortex_panic!("ScalarValue is not a Binary"),
242 }
243 }
244
245 /// Returns the list elements, panicking if the value is not a [`List`][ScalarValue::List].
246 pub fn into_list(self) -> Vec<Option<ScalarValue>> {
247 match self {
248 ScalarValue::List(elements) => elements,
249 _ => vortex_panic!("ScalarValue is not a List"),
250 }
251 }
252}