Skip to main content

vortex_array/scalar/convert/
from_scalar.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4//! Conversions from scalars into other types.
5
6use vortex_buffer::BufferString;
7use vortex_buffer::ByteBuffer;
8use vortex_error::VortexError;
9use vortex_error::VortexResult;
10use vortex_error::vortex_err;
11
12use crate::scalar::BinaryScalar;
13use crate::scalar::BoolScalar;
14use crate::scalar::DecimalScalar;
15use crate::scalar::ExtScalar;
16use crate::scalar::ListScalar;
17use crate::scalar::PrimitiveScalar;
18use crate::scalar::Scalar;
19use crate::scalar::StructScalar;
20use crate::scalar::Utf8Scalar;
21
22////////////////////////////////////////////////////////////////////////////////////////////////////
23// Typed scalar conversions.
24//
25// These delegate to the `as_*_opt()` methods on [`Scalar`].
26////////////////////////////////////////////////////////////////////////////////////////////////////
27
28impl<'a> TryFrom<&'a Scalar> for BoolScalar<'a> {
29    type Error = VortexError;
30
31    fn try_from(value: &'a Scalar) -> VortexResult<Self> {
32        value
33            .as_bool_opt()
34            .ok_or_else(|| vortex_err!("Expected bool scalar, found {}", value.dtype()))
35    }
36}
37
38impl<'a> TryFrom<&'a Scalar> for PrimitiveScalar<'a> {
39    type Error = VortexError;
40
41    fn try_from(value: &'a Scalar) -> VortexResult<Self> {
42        value
43            .as_primitive_opt()
44            .ok_or_else(|| vortex_err!("Expected primitive scalar, found {}", value.dtype()))
45    }
46}
47
48impl<'a> TryFrom<&'a Scalar> for DecimalScalar<'a> {
49    type Error = VortexError;
50
51    fn try_from(value: &'a Scalar) -> VortexResult<Self> {
52        value
53            .as_decimal_opt()
54            .ok_or_else(|| vortex_err!("Expected decimal scalar, found {}", value.dtype()))
55    }
56}
57
58impl<'a> TryFrom<&'a Scalar> for Utf8Scalar<'a> {
59    type Error = VortexError;
60
61    fn try_from(value: &'a Scalar) -> VortexResult<Self> {
62        value
63            .as_utf8_opt()
64            .ok_or_else(|| vortex_err!("Expected utf8 scalar, found {}", value.dtype()))
65    }
66}
67
68impl<'a> TryFrom<&'a Scalar> for BinaryScalar<'a> {
69    type Error = VortexError;
70
71    fn try_from(value: &'a Scalar) -> VortexResult<Self> {
72        value
73            .as_binary_opt()
74            .ok_or_else(|| vortex_err!("Expected binary scalar, found {}", value.dtype()))
75    }
76}
77
78impl<'a> TryFrom<&'a Scalar> for StructScalar<'a> {
79    type Error = VortexError;
80
81    fn try_from(value: &'a Scalar) -> VortexResult<Self> {
82        value
83            .as_struct_opt()
84            .ok_or_else(|| vortex_err!("Expected struct scalar, found {}", value.dtype()))
85    }
86}
87
88impl<'a> TryFrom<&'a Scalar> for ListScalar<'a> {
89    type Error = VortexError;
90
91    fn try_from(value: &'a Scalar) -> VortexResult<Self> {
92        value
93            .as_list_opt()
94            .ok_or_else(|| vortex_err!("Expected list scalar, found {}", value.dtype()))
95    }
96}
97
98impl<'a> TryFrom<&'a Scalar> for ExtScalar<'a> {
99    type Error = VortexError;
100
101    fn try_from(value: &'a Scalar) -> VortexResult<Self> {
102        value
103            .as_extension_opt()
104            .ok_or_else(|| vortex_err!("Expected extension scalar, found {}", value.dtype()))
105    }
106}
107
108////////////////////////////////////////////////////////////////////////////////////////////////////
109// Boolean conversions.
110////////////////////////////////////////////////////////////////////////////////////////////////////
111
112impl TryFrom<&Scalar> for bool {
113    type Error = VortexError;
114
115    fn try_from(value: &Scalar) -> VortexResult<Self> {
116        <Option<bool>>::try_from(value)?
117            .ok_or_else(|| vortex_err!("Can't extract present value from null scalar"))
118    }
119}
120
121impl TryFrom<&Scalar> for Option<bool> {
122    type Error = VortexError;
123
124    fn try_from(value: &Scalar) -> VortexResult<Self> {
125        Ok(value
126            .as_bool_opt()
127            .ok_or_else(|| vortex_err!("Expected bool scalar, found {}", value.dtype()))?
128            .value())
129    }
130}
131
132impl TryFrom<Scalar> for bool {
133    type Error = VortexError;
134
135    fn try_from(value: Scalar) -> VortexResult<Self> {
136        Self::try_from(&value)
137    }
138}
139
140impl TryFrom<Scalar> for Option<bool> {
141    type Error = VortexError;
142
143    fn try_from(value: Scalar) -> VortexResult<Self> {
144        Self::try_from(&value)
145    }
146}
147
148////////////////////////////////////////////////////////////////////////////////////////////////////
149// Binary conversions.
150////////////////////////////////////////////////////////////////////////////////////////////////////
151
152impl<'a> TryFrom<&'a Scalar> for ByteBuffer {
153    type Error = VortexError;
154
155    fn try_from(scalar: &'a Scalar) -> VortexResult<Self> {
156        let binary = scalar
157            .as_binary_opt()
158            .ok_or_else(|| vortex_err!("Cannot extract buffer from non-buffer scalar"))?;
159
160        binary
161            .value()
162            .cloned()
163            .ok_or_else(|| vortex_err!("Cannot extract present value from null scalar"))
164    }
165}
166
167impl<'a> TryFrom<&'a Scalar> for Option<ByteBuffer> {
168    type Error = VortexError;
169
170    fn try_from(scalar: &'a Scalar) -> VortexResult<Self> {
171        Ok(scalar
172            .as_binary_opt()
173            .ok_or_else(|| vortex_err!("Cannot extract buffer from non-buffer scalar"))?
174            .value()
175            .cloned())
176    }
177}
178
179impl TryFrom<Scalar> for ByteBuffer {
180    type Error = VortexError;
181
182    fn try_from(scalar: Scalar) -> VortexResult<Self> {
183        Self::try_from(&scalar)
184    }
185}
186
187impl TryFrom<Scalar> for Option<ByteBuffer> {
188    type Error = VortexError;
189
190    fn try_from(scalar: Scalar) -> VortexResult<Self> {
191        Self::try_from(&scalar)
192    }
193}
194
195////////////////////////////////////////////////////////////////////////////////////////////////////
196// UTF-8 conversions.
197////////////////////////////////////////////////////////////////////////////////////////////////////
198
199impl<'a> TryFrom<&'a Scalar> for String {
200    type Error = VortexError;
201
202    fn try_from(value: &'a Scalar) -> Result<Self, Self::Error> {
203        Ok(BufferString::try_from(value)?.to_string())
204    }
205}
206
207impl TryFrom<Scalar> for String {
208    type Error = VortexError;
209
210    fn try_from(value: Scalar) -> Result<Self, Self::Error> {
211        Ok(BufferString::try_from(value)?.to_string())
212    }
213}
214
215impl<'a> TryFrom<&'a Scalar> for BufferString {
216    type Error = VortexError;
217
218    fn try_from(scalar: &'a Scalar) -> VortexResult<Self> {
219        <Option<BufferString>>::try_from(scalar)?
220            .ok_or_else(|| vortex_err!("Can't extract present value from null scalar"))
221    }
222}
223
224impl TryFrom<Scalar> for BufferString {
225    type Error = VortexError;
226
227    fn try_from(scalar: Scalar) -> Result<Self, Self::Error> {
228        Self::try_from(&scalar)
229    }
230}
231
232impl<'a> TryFrom<&'a Scalar> for Option<BufferString> {
233    type Error = VortexError;
234
235    fn try_from(scalar: &'a Scalar) -> Result<Self, Self::Error> {
236        Ok(scalar
237            .as_utf8_opt()
238            .ok_or_else(|| vortex_err!("Expected utf8 scalar, found {}", scalar.dtype()))?
239            .value()
240            .cloned())
241    }
242}
243
244impl TryFrom<Scalar> for Option<BufferString> {
245    type Error = VortexError;
246
247    fn try_from(scalar: Scalar) -> Result<Self, Self::Error> {
248        Self::try_from(&scalar)
249    }
250}
251
252////////////////////////////////////////////////////////////////////////////////////////////////////
253// List (`Vec`) conversions.
254////////////////////////////////////////////////////////////////////////////////////////////////////
255
256impl<T> TryFrom<Scalar> for Vec<T>
257where
258    T: for<'b> TryFrom<&'b Scalar, Error = VortexError>,
259{
260    type Error = VortexError;
261
262    fn try_from(value: Scalar) -> Result<Self, Self::Error> {
263        Vec::try_from(&value)
264    }
265}
266
267impl<'a, T> TryFrom<&'a Scalar> for Vec<T>
268where
269    T: for<'b> TryFrom<&'b Scalar, Error = VortexError>,
270{
271    type Error = VortexError;
272
273    fn try_from(value: &'a Scalar) -> Result<Self, Self::Error> {
274        value
275            .as_list_opt()
276            .ok_or_else(|| vortex_err!("Expected list scalar, found {}", value.dtype()))?
277            .elements()
278            .ok_or_else(|| vortex_err!("Expected non-null list"))?
279            .into_iter()
280            .map(|e| T::try_from(&e))
281            .collect::<VortexResult<Vec<T>>>()
282    }
283}