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        value
117            .as_bool_opt()
118            .ok_or_else(|| vortex_err!("Expected bool scalar, found {}", value.dtype()))?
119            .value()
120            .ok_or_else(|| vortex_err!("Can't extract present value from null scalar"))
121    }
122}
123
124impl TryFrom<&Scalar> for Option<bool> {
125    type Error = VortexError;
126
127    fn try_from(value: &Scalar) -> VortexResult<Self> {
128        Ok(value
129            .as_bool_opt()
130            .ok_or_else(|| vortex_err!("Expected bool scalar, found {}", value.dtype()))?
131            .value())
132    }
133}
134
135impl TryFrom<Scalar> for bool {
136    type Error = VortexError;
137
138    fn try_from(value: Scalar) -> VortexResult<Self> {
139        Self::try_from(&value)
140    }
141}
142
143impl TryFrom<Scalar> for Option<bool> {
144    type Error = VortexError;
145
146    fn try_from(value: Scalar) -> VortexResult<Self> {
147        Self::try_from(&value)
148    }
149}
150
151////////////////////////////////////////////////////////////////////////////////////////////////////
152// Binary conversions.
153////////////////////////////////////////////////////////////////////////////////////////////////////
154
155impl<'a> TryFrom<&'a Scalar> for ByteBuffer {
156    type Error = VortexError;
157
158    fn try_from(scalar: &'a Scalar) -> VortexResult<Self> {
159        let binary = scalar
160            .as_binary_opt()
161            .ok_or_else(|| vortex_err!("Cannot extract buffer from non-buffer scalar"))?;
162
163        binary
164            .value()
165            .cloned()
166            .ok_or_else(|| vortex_err!("Cannot extract present value from null scalar"))
167    }
168}
169
170impl<'a> TryFrom<&'a Scalar> for Option<ByteBuffer> {
171    type Error = VortexError;
172
173    fn try_from(scalar: &'a Scalar) -> VortexResult<Self> {
174        Ok(scalar
175            .as_binary_opt()
176            .ok_or_else(|| vortex_err!("Cannot extract buffer from non-buffer scalar"))?
177            .value()
178            .cloned())
179    }
180}
181
182impl TryFrom<Scalar> for ByteBuffer {
183    type Error = VortexError;
184
185    fn try_from(scalar: Scalar) -> VortexResult<Self> {
186        Self::try_from(&scalar)
187    }
188}
189
190impl TryFrom<Scalar> for Option<ByteBuffer> {
191    type Error = VortexError;
192
193    fn try_from(scalar: Scalar) -> VortexResult<Self> {
194        Self::try_from(&scalar)
195    }
196}
197
198////////////////////////////////////////////////////////////////////////////////////////////////////
199// UTF-8 conversions.
200////////////////////////////////////////////////////////////////////////////////////////////////////
201
202impl<'a> TryFrom<&'a Scalar> for String {
203    type Error = VortexError;
204
205    fn try_from(value: &'a Scalar) -> Result<Self, Self::Error> {
206        Ok(BufferString::try_from(value)?.to_string())
207    }
208}
209
210impl TryFrom<Scalar> for String {
211    type Error = VortexError;
212
213    fn try_from(value: Scalar) -> Result<Self, Self::Error> {
214        Ok(BufferString::try_from(value)?.to_string())
215    }
216}
217
218impl<'a> TryFrom<&'a Scalar> for BufferString {
219    type Error = VortexError;
220
221    fn try_from(scalar: &'a Scalar) -> VortexResult<Self> {
222        <Option<BufferString>>::try_from(scalar)?
223            .ok_or_else(|| vortex_err!("Can't extract present value from null scalar"))
224    }
225}
226
227impl TryFrom<Scalar> for BufferString {
228    type Error = VortexError;
229
230    fn try_from(scalar: Scalar) -> Result<Self, Self::Error> {
231        Self::try_from(&scalar)
232    }
233}
234
235impl<'a> TryFrom<&'a Scalar> for Option<BufferString> {
236    type Error = VortexError;
237
238    fn try_from(scalar: &'a Scalar) -> Result<Self, Self::Error> {
239        Ok(scalar
240            .as_utf8_opt()
241            .ok_or_else(|| vortex_err!("Expected utf8 scalar, found {}", scalar.dtype()))?
242            .value()
243            .cloned())
244    }
245}
246
247impl TryFrom<Scalar> for Option<BufferString> {
248    type Error = VortexError;
249
250    fn try_from(scalar: Scalar) -> Result<Self, Self::Error> {
251        Self::try_from(&scalar)
252    }
253}
254
255////////////////////////////////////////////////////////////////////////////////////////////////////
256// List (`Vec`) conversions.
257////////////////////////////////////////////////////////////////////////////////////////////////////
258
259impl<T> TryFrom<Scalar> for Vec<T>
260where
261    T: for<'b> TryFrom<&'b Scalar, Error = VortexError>,
262{
263    type Error = VortexError;
264
265    fn try_from(value: Scalar) -> Result<Self, Self::Error> {
266        Vec::try_from(&value)
267    }
268}
269
270impl<'a, T> TryFrom<&'a Scalar> for Vec<T>
271where
272    T: for<'b> TryFrom<&'b Scalar, Error = VortexError>,
273{
274    type Error = VortexError;
275
276    fn try_from(value: &'a Scalar) -> Result<Self, Self::Error> {
277        value
278            .as_list_opt()
279            .ok_or_else(|| vortex_err!("Expected list scalar, found {}", value.dtype()))?
280            .elements()
281            .ok_or_else(|| vortex_err!("Expected non-null list"))?
282            .into_iter()
283            .map(|e| T::try_from(&e))
284            .collect::<VortexResult<Vec<T>>>()
285    }
286}