1#[cfg(feature = "time")]
2use tea_time::TimeUnitTrait;
3#[cfg(feature = "time")]
4use tea_time::{DateTime, TimeDelta, TimeUnit};
5
6#[derive(PartialEq, Eq, Debug)]
11pub enum DataType {
12 Bool,
14 F32,
16 F64,
18 I32,
20 I64,
22 U8,
24 U64,
26 Usize,
28 Str,
30 String,
32 Object,
34 OptBool,
36 OptF32,
38 OptF64,
40 OptI32,
42 OptI64,
44 OptUsize,
46 VecUsize,
48 #[cfg(feature = "time")]
50 DateTime(TimeUnit),
51 #[cfg(feature = "time")]
53 TimeDelta,
54 Unknown,
56}
57
58pub trait GetDataType {
60 fn dtype() -> DataType
66 where
67 Self: Sized;
68}
69
70macro_rules! impl_datatype {
71 ($tyname:ident, $physical:ty) => {
72 impl GetDataType for $physical {
73 #[inline(always)]
74 fn dtype() -> DataType {
75 DataType::$tyname
76 }
77 }
78 };
79}
80
81impl DataType {
82 #[inline(always)]
88 pub fn is_float(&self) -> bool {
89 use DataType::*;
90 matches!(self, F32 | F64 | OptF32 | OptF64)
91 }
92
93 #[inline(always)]
99 pub fn is_int(&self) -> bool {
100 use DataType::*;
101 matches!(self, I32 | I64 | Usize | U64 | OptUsize | OptI32 | OptI64)
102 }
103
104 #[inline]
110 pub fn is_time(&self) -> bool {
111 #[cfg(feature = "time")]
112 {
113 use DataType::*;
114 matches!(self, DateTime(_))
115 }
116 #[cfg(not(feature = "time"))]
117 {
118 false
119 }
120 }
121
122 pub fn float(self) -> Self {
128 use DataType::*;
129 match self {
130 F32 => F32,
131 I32 => F32,
132 I64 => F64,
133 Usize => F64,
134 U64 => F64,
135 OptUsize => F64,
136 OptI32 => OptF32,
137 OptI64 => OptF64,
138 OptF32 => OptF32,
139 OptF64 => OptF64,
140 _ => F64,
141 }
142 }
143
144 pub fn int(self) -> Self {
150 use DataType::*;
151 match self {
152 I32 => I32,
153 F32 => I32,
154 F64 => I64,
155 Usize => Usize,
156 U64 => I64,
157 OptUsize => OptUsize,
158 OptI32 => OptI32,
159 OptI64 => OptI64,
160 OptF32 => OptI32,
161 OptF64 => OptI64,
162 _ => I64,
163 }
164 }
165}
166
167impl_datatype!(Bool, bool);
168impl_datatype!(U8, u8);
169impl_datatype!(F32, f32);
170impl_datatype!(F64, f64);
171impl_datatype!(I32, i32);
172impl_datatype!(I64, i64);
173impl_datatype!(U64, u64);
174impl_datatype!(Usize, usize);
175impl_datatype!(String, String);
176impl_datatype!(OptBool, Option<bool>);
177impl_datatype!(OptF32, Option<f32>);
178impl_datatype!(OptF64, Option<f64>);
179impl_datatype!(OptI32, Option<i32>);
180impl_datatype!(OptI64, Option<i64>);
181impl_datatype!(OptUsize, Option<usize>);
182impl_datatype!(VecUsize, Vec<usize>);
183
184#[cfg(feature = "time")]
185impl<U: TimeUnitTrait> GetDataType for DateTime<U> {
186 #[inline(always)]
187 fn dtype() -> DataType {
188 DataType::DateTime(U::unit())
189 }
190}
191
192#[cfg(feature = "time")]
193impl_datatype!(TimeDelta, TimeDelta);
194
195impl GetDataType for &str {
196 #[inline(always)]
197 fn dtype() -> DataType {
198 DataType::Str
199 }
200}
201
202#[cfg(feature = "polars")]
203const fn into_pl_dtype(dt: &DataType) -> tea_deps::polars::prelude::DataType {
204 use tea_deps::polars::prelude::{DataType as PlDataType, UnknownKind};
205 match dt {
206 DataType::Bool => PlDataType::Boolean,
207 DataType::F32 => PlDataType::Float32,
208 DataType::F64 => PlDataType::Float64,
209 DataType::I32 => PlDataType::Int32,
210 DataType::I64 => PlDataType::Int64,
211 DataType::U8 => PlDataType::UInt8,
212 DataType::U64 => PlDataType::UInt64,
213 DataType::Usize => PlDataType::UInt64,
214 DataType::String => PlDataType::String,
215 _ => PlDataType::Unknown(UnknownKind::Any),
216 }
217}
218
219#[cfg(feature = "polars")]
220const fn from_pl_dtype(dt: &tea_deps::polars::prelude::DataType) -> DataType {
221 use tea_deps::polars::prelude::DataType as PlDataType;
222 match dt {
223 PlDataType::Boolean => DataType::Bool,
224 PlDataType::Float32 => DataType::F32,
225 PlDataType::Float64 => DataType::F64,
226 PlDataType::Int32 => DataType::I32,
227 PlDataType::Int64 => DataType::I64,
228 PlDataType::UInt8 => DataType::U8,
229 PlDataType::UInt64 => DataType::U64,
230 PlDataType::String => DataType::String,
231 _ => DataType::Unknown,
232 }
233}
234
235#[cfg(feature = "polars")]
236impl From<DataType> for tea_deps::polars::prelude::DataType {
237 #[inline(always)]
238 fn from(dt: DataType) -> Self {
239 into_pl_dtype(&dt)
240 }
241}
242
243#[cfg(feature = "polars")]
244impl From<&DataType> for tea_deps::polars::prelude::DataType {
245 #[inline(always)]
246 fn from(dt: &DataType) -> Self {
247 into_pl_dtype(dt)
248 }
249}
250
251#[cfg(feature = "polars")]
252impl From<tea_deps::polars::prelude::DataType> for DataType {
253 #[inline(always)]
254 fn from(dt: tea_deps::polars::prelude::DataType) -> Self {
255 from_pl_dtype(&dt)
256 }
257}
258
259#[cfg(feature = "polars")]
260impl From<&tea_deps::polars::prelude::DataType> for DataType {
261 #[inline(always)]
262 fn from(dt: &tea_deps::polars::prelude::DataType) -> Self {
263 from_pl_dtype(dt)
264 }
265}
266
267#[cfg(test)]
268mod tests {
269 use super::*;
270
271 #[test]
272 #[cfg(feature = "polars")]
273 fn test_from_datatype() {
274 use tea_deps::polars::prelude::DataType as PlDataType;
275 let dt: PlDataType = DataType::Bool.into();
276 assert_eq!(dt, PlDataType::Boolean);
277 let dt: PlDataType = DataType::F32.into();
278 assert_eq!(dt, PlDataType::Float32);
279 let dt: PlDataType = DataType::F64.into();
280 assert_eq!(dt, PlDataType::Float64);
281 let dt: PlDataType = DataType::I32.into();
282 assert_eq!(dt, PlDataType::Int32);
283 let dt: PlDataType = DataType::I64.into();
284 assert_eq!(dt, PlDataType::Int64);
285 let dt: PlDataType = DataType::U8.into();
286 assert_eq!(dt, PlDataType::UInt8);
287 let dt: PlDataType = DataType::U64.into();
288 assert_eq!(dt, PlDataType::UInt64);
289 let dt: PlDataType = DataType::Usize.into();
290 assert_eq!(dt, PlDataType::UInt64);
291 let dt: PlDataType = DataType::String.into();
292 assert_eq!(dt, PlDataType::String);
293 let dt: PlDataType = DataType::Object.into();
294 assert!(matches!(dt, PlDataType::Unknown(_)));
295 }
296 #[test]
297 #[cfg(feature = "polars")]
298 fn test_from_pldatatype() {
299 use tea_deps::polars::prelude::{DataType as PlDataType, UnknownKind};
300
301 assert_eq!(DataType::from(PlDataType::Boolean), DataType::Bool);
302 assert_eq!(DataType::from(PlDataType::Float32), DataType::F32);
303 assert_eq!(DataType::from(PlDataType::Float64), DataType::F64);
304 assert_eq!(DataType::from(PlDataType::Int32), DataType::I32);
305 assert_eq!(DataType::from(PlDataType::Int64), DataType::I64);
306 assert_eq!(DataType::from(PlDataType::UInt8), DataType::U8);
307 assert_eq!(DataType::from(PlDataType::UInt64), DataType::U64);
308 assert_eq!(DataType::from(PlDataType::String), DataType::String);
309
310 if let DataType::Unknown = DataType::from(PlDataType::Unknown(UnknownKind::Any)) {
312 } else {
314 panic!("Expected Unknown DataType for PlDataType::Object");
315 }
316
317 assert_eq!(DataType::from(&PlDataType::Boolean), DataType::Bool);
319 }
320}