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