vortex_vector/
datum.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use vortex_dtype::NativeDecimalType;
5use vortex_dtype::NativePType;
6use vortex_dtype::PType;
7
8use crate::Scalar;
9use crate::Vector;
10use crate::binaryview::BinaryType;
11use crate::binaryview::BinaryViewScalar;
12use crate::binaryview::BinaryViewType;
13use crate::binaryview::BinaryViewVector;
14use crate::binaryview::StringType;
15use crate::bool::BoolScalar;
16use crate::bool::BoolVector;
17use crate::decimal::DScalar;
18use crate::decimal::DVector;
19use crate::decimal::DecimalScalar;
20use crate::decimal::DecimalVector;
21use crate::fixed_size_list::FixedSizeListScalar;
22use crate::fixed_size_list::FixedSizeListVector;
23use crate::listview::ListViewScalar;
24use crate::listview::ListViewVector;
25use crate::null::NullScalar;
26use crate::null::NullVector;
27use crate::primitive::PScalar;
28use crate::primitive::PVector;
29use crate::primitive::PrimitiveScalar;
30use crate::primitive::PrimitiveVector;
31use crate::struct_::StructScalar;
32use crate::struct_::StructVector;
33
34/// Represents either a scalar or vector value.
35#[derive(Clone, Debug)]
36pub enum Datum {
37    /// A scalar value.
38    Scalar(Scalar),
39    /// A vector value.
40    Vector(Vector),
41}
42
43impl From<Scalar> for Datum {
44    fn from(value: Scalar) -> Self {
45        Datum::Scalar(value)
46    }
47}
48
49impl From<Vector> for Datum {
50    fn from(value: Vector) -> Self {
51        Datum::Vector(value)
52    }
53}
54
55impl Datum {
56    /// Returns the scalar value if this `Datum` is a `Scalar`, otherwise returns `None`.
57    pub fn into_scalar(self) -> Option<Scalar> {
58        match self {
59            Datum::Scalar(scalar) => Some(scalar),
60            Datum::Vector(_) => None,
61        }
62    }
63
64    /// Returns the vector value if this `Datum` is a `Vector`, otherwise returns `None`.
65    pub fn into_vector(self) -> Option<Vector> {
66        match self {
67            Datum::Scalar(_) => None,
68            Datum::Vector(vector) => Some(vector),
69        }
70    }
71
72    /// Returns a reference to the scalar value if this `Datum` is a `Scalar`, otherwise returns `None`.
73    pub fn as_scalar(&self) -> Option<&Scalar> {
74        match self {
75            Datum::Scalar(scalar) => Some(scalar),
76            Datum::Vector(_) => None,
77        }
78    }
79
80    /// Returns a reference to the vector value if this `Datum` is a `Vector`, otherwise returns `None`.
81    pub fn as_vector(&self) -> Option<&Vector> {
82        match self {
83            Datum::Scalar(_) => None,
84            Datum::Vector(vector) => Some(vector),
85        }
86    }
87}
88
89impl Datum {
90    /// Converts the `Datum` into a `NullDatum`.
91    pub fn into_null(self) -> NullDatum {
92        match self {
93            Datum::Scalar(scalar) => NullDatum::Scalar(scalar.into_null()),
94            Datum::Vector(vector) => NullDatum::Vector(vector.into_null()),
95        }
96    }
97
98    /// Converts the `Datum` into a `BoolDatum`.
99    pub fn into_bool(self) -> BoolDatum {
100        match self {
101            Datum::Scalar(scalar) => BoolDatum::Scalar(scalar.into_bool()),
102            Datum::Vector(vector) => BoolDatum::Vector(vector.into_bool()),
103        }
104    }
105
106    /// Converts the `Datum` into a `PrimitiveDatum`.
107    pub fn into_primitive(self) -> PrimitiveDatum {
108        match self {
109            Datum::Scalar(scalar) => PrimitiveDatum::Scalar(scalar.into_primitive()),
110            Datum::Vector(vector) => PrimitiveDatum::Vector(vector.into_primitive()),
111        }
112    }
113
114    /// Converts the `Datum` into a `DecimalDatum`.
115    pub fn into_decimal(self) -> DecimalDatum {
116        match self {
117            Datum::Scalar(scalar) => DecimalDatum::Scalar(scalar.into_decimal()),
118            Datum::Vector(vector) => DecimalDatum::Vector(vector.into_decimal()),
119        }
120    }
121
122    /// Converts the `Datum` into a `ListViewDatum`.
123    pub fn into_list(self) -> ListViewDatum {
124        match self {
125            Datum::Scalar(scalar) => ListViewDatum::Scalar(scalar.into_list()),
126            Datum::Vector(vector) => ListViewDatum::Vector(vector.into_list()),
127        }
128    }
129
130    /// Converts the `Datum` into a `FixedSizeListDatum`.
131    pub fn into_fixed_size_list(self) -> FixedSizeListDatum {
132        match self {
133            Datum::Scalar(scalar) => FixedSizeListDatum::Scalar(scalar.into_fixed_size_list()),
134            Datum::Vector(vector) => FixedSizeListDatum::Vector(vector.into_fixed_size_list()),
135        }
136    }
137
138    /// Converts the `Datum` into a `StructDatum`.
139    pub fn into_struct(self) -> StructDatum {
140        match self {
141            Datum::Scalar(scalar) => StructDatum::Scalar(scalar.into_struct()),
142            Datum::Vector(vector) => StructDatum::Vector(vector.into_struct()),
143        }
144    }
145
146    /// Converts the `Datum` into a `TypedDatum`.
147    pub fn into_typed(self) -> TypedDatum {
148        match self {
149            Datum::Scalar(sc) => match sc {
150                Scalar::Null(s) => TypedDatum::Null(NullDatum::Scalar(s)),
151                Scalar::Bool(s) => TypedDatum::Bool(BoolDatum::Scalar(s)),
152                Scalar::Decimal(s) => TypedDatum::Decimal(DecimalDatum::Scalar(s)),
153                Scalar::Primitive(s) => TypedDatum::Primitive(PrimitiveDatum::Scalar(s)),
154                Scalar::String(s) => TypedDatum::String(BinaryViewDatum::Scalar(s)),
155                Scalar::Binary(s) => TypedDatum::Binary(BinaryViewDatum::Scalar(s)),
156                Scalar::List(s) => TypedDatum::List(ListViewDatum::Scalar(s)),
157                Scalar::FixedSizeList(s) => {
158                    TypedDatum::FixedSizeList(FixedSizeListDatum::Scalar(s))
159                }
160                Scalar::Struct(s) => TypedDatum::Struct(StructDatum::Scalar(s)),
161            },
162            Datum::Vector(vec) => match vec {
163                Vector::Null(v) => TypedDatum::Null(NullDatum::Vector(v)),
164                Vector::Bool(v) => TypedDatum::Bool(BoolDatum::Vector(v)),
165                Vector::Decimal(v) => TypedDatum::Decimal(DecimalDatum::Vector(v)),
166                Vector::Primitive(v) => TypedDatum::Primitive(PrimitiveDatum::Vector(v)),
167                Vector::String(v) => TypedDatum::String(BinaryViewDatum::Vector(v)),
168                Vector::Binary(v) => TypedDatum::Binary(BinaryViewDatum::Vector(v)),
169                Vector::List(v) => TypedDatum::List(ListViewDatum::Vector(v)),
170                Vector::FixedSizeList(v) => {
171                    TypedDatum::FixedSizeList(FixedSizeListDatum::Vector(v))
172                }
173                Vector::Struct(v) => TypedDatum::Struct(StructDatum::Vector(v)),
174            },
175        }
176    }
177}
178
179macro_rules! datum {
180    // Non-generic version
181    ($Name:ident) => {
182        paste::paste! {
183            #[doc = concat!("Datum enum for `", stringify!($Name), "`.")]
184            pub enum [<$Name Datum>] {
185                /// Scalar variant
186                Scalar([<$Name Scalar>]),
187                /// Vector variant
188                Vector([<$Name Vector>]),
189            }
190
191            impl From<[<$Name Datum>]> for Datum {
192                fn from(val: [<$Name Datum>]) -> Self {
193                    match val {
194                        [<$Name Datum>]::Scalar(scalar) => Datum::Scalar(Scalar::from(scalar)),
195                        [<$Name Datum>]::Vector(vector) => Datum::Vector(Vector::from(vector)),
196                    }
197                }
198            }
199
200            impl From<[<$Name Scalar>]> for Datum {
201                fn from(val: [<$Name Scalar>]) -> Self {
202                    Datum::Scalar(Scalar::from(val))
203                }
204            }
205
206            impl From<[<$Name Scalar>]> for [<$Name Datum>] {
207                fn from(val: [<$Name Scalar>]) -> Self {
208                    [<$Name Datum>]::Scalar(val)
209                }
210            }
211
212            impl From<[<$Name Vector>]> for [<$Name Datum>] {
213                fn from(val: [<$Name Vector>]) -> Self {
214                    [<$Name Datum>]::Vector(val)
215                }
216            }
217        }
218    };
219
220    // Generic version with trait bound
221    ($Name:ident < $T:ident : $Bound:path >) => {
222        paste::paste! {
223            #[doc = concat!("Datum enum for `", stringify!([<$Name Datum>]<$T: $Bound>), "`.")]
224            pub enum [<$Name Datum>]<$T: $Bound> {
225                /// Scalar variant
226                Scalar([<$Name Scalar>]<$T>),
227                /// Vector variant
228                Vector([<$Name Vector>]<$T>),
229            }
230
231            impl<$T: $Bound> From<[<$Name Datum>]<$T>> for Datum {
232                fn from(val: [<$Name Datum>]<$T>) -> Self {
233                    match val {
234                        [<$Name Datum>]::Scalar(scalar) => Datum::Scalar(Scalar::from(scalar)),
235                        [<$Name Datum>]::Vector(vector) => Datum::Vector(Vector::from(vector)),
236                    }
237                }
238            }
239
240            impl<$T: $Bound> From<[<$Name Scalar>]<$T>> for Datum {
241                fn from(val: [<$Name Scalar>]<$T>) -> Self {
242                    Datum::Scalar(Scalar::from(val))
243                }
244            }
245
246            impl<$T: $Bound> From<[<$Name Scalar>]<$T>> for [<$Name Datum>]<$T> {
247                fn from(val: [<$Name Scalar>]<$T>) -> Self {
248                    [<$Name Datum>]::Scalar(val)
249                }
250            }
251
252            impl<$T: $Bound> From<[<$Name Vector>]<$T>> for [<$Name Datum>]<$T> {
253                fn from(val: [<$Name Vector>]<$T>) -> Self {
254                    [<$Name Datum>]::Vector(val)
255                }
256            }
257        }
258    };
259}
260
261datum!(Null);
262datum!(Bool);
263datum!(Primitive);
264datum!(P<T: NativePType>);
265datum!(Decimal);
266datum!(D<D: NativeDecimalType>);
267datum!(BinaryView<T: BinaryViewType>);
268datum!(ListView);
269datum!(FixedSizeList);
270datum!(Struct);
271
272impl PrimitiveDatum {
273    /// ptype from datum
274    pub fn ptype(&self) -> PType {
275        match self {
276            PrimitiveDatum::Scalar(sc) => sc.ptype(),
277            PrimitiveDatum::Vector(sc) => sc.ptype(),
278        }
279    }
280}
281
282/// A variant of [`Datum`] that is typed.
283pub enum TypedDatum {
284    /// Null datum.
285    Null(NullDatum),
286    /// Boolean datum.
287    Bool(BoolDatum),
288    /// Decimal datum.
289    Decimal(DecimalDatum),
290    /// Primitive datum.
291    Primitive(PrimitiveDatum),
292    /// String datum
293    String(BinaryViewDatum<StringType>),
294    /// Binary datum
295    Binary(BinaryViewDatum<BinaryType>),
296    /// List datum.
297    List(ListViewDatum),
298    /// fsl datum.
299    FixedSizeList(FixedSizeListDatum),
300    /// struct datum.
301    Struct(StructDatum),
302}