Skip to main content

radiate_expr/datatype/
dtype.rs

1use super::{Field, Scalar};
2use radiate_utils::{Float, Integer};
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5use std::fmt::Display;
6
7pub mod dtype_names {
8    pub const NULL: &str = "null";
9    pub const BOOLEAN: &str = "boolean";
10    pub const UINT8: &str = "uint8";
11    pub const UINT16: &str = "uint16";
12    pub const UINT32: &str = "uint32";
13    pub const UINT64: &str = "uint64";
14    pub const UINT128: &str = "uint128";
15    pub const INT8: &str = "int8";
16    pub const INT16: &str = "int16";
17    pub const INT32: &str = "int32";
18    pub const INT64: &str = "int64";
19    pub const INT128: &str = "int128";
20    pub const FLOAT32: &str = "float32";
21    pub const FLOAT64: &str = "float64";
22    pub const USIZE: &str = "usize";
23    pub const BINARY: &str = "binary";
24    pub const CHAR: &str = "char";
25    pub const STRING: &str = "string";
26    pub const DURATION: &str = "duration";
27    pub const VEC: &str = "vec";
28    pub const STRUCT: &str = "struct";
29}
30
31#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
32#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
33pub enum DataType {
34    #[default]
35    Null,
36
37    UInt8,
38    UInt16,
39    UInt32,
40    UInt64,
41    UInt128,
42
43    Int8,
44    Int16,
45    Int32,
46    Int64,
47    Int128,
48
49    Float32,
50    Float64,
51
52    Duration,
53
54    Boolean,
55
56    Char,
57    String,
58
59    List(Box<DataType>),
60    Struct(Vec<Field>),
61}
62
63impl DataType {
64    pub fn is_nested(&self) -> bool {
65        use DataType as D;
66        matches!(self, D::List(_) | D::Struct(_))
67    }
68
69    pub fn is_numeric(&self) -> bool {
70        use DataType as D;
71        matches!(
72            self,
73            D::Int8
74                | D::Int16
75                | D::Int32
76                | D::Int64
77                | D::Int128
78                | D::UInt8
79                | D::UInt16
80                | D::UInt32
81                | D::UInt64
82                | D::Float32
83                | D::Float64
84        )
85    }
86
87    pub fn is_primitive(&self) -> bool {
88        use DataType as D;
89        matches!(
90            self,
91            D::Null
92                | D::Boolean
93                | D::Int8
94                | D::Int16
95                | D::Int32
96                | D::Int64
97                | D::Int128
98                | D::UInt8
99                | D::UInt16
100                | D::UInt32
101                | D::UInt64
102                | D::Float32
103                | D::Float64
104        )
105    }
106
107    pub fn max(&self) -> Option<Scalar> {
108        use DataType as D;
109        match self {
110            D::Int8 => Some(Scalar::from(<i8 as Integer>::MAX)),
111            D::Int16 => Some(Scalar::from(<i16 as Integer>::MAX)),
112            D::Int32 => Some(Scalar::from(<i32 as Integer>::MAX)),
113            D::Int64 => Some(Scalar::from(<i64 as Integer>::MAX)),
114            D::Int128 => Some(Scalar::from(<i128 as Integer>::MAX)),
115            D::UInt8 => Some(Scalar::from(<u8 as Integer>::MAX)),
116            D::UInt16 => Some(Scalar::from(<u16 as Integer>::MAX)),
117            D::UInt32 => Some(Scalar::from(<u32 as Integer>::MAX)),
118            D::UInt64 => Some(Scalar::from(<u64 as Integer>::MAX)),
119            D::UInt128 => Some(Scalar::from(<u128 as Integer>::MAX)),
120            D::Float32 => Some(Scalar::from(<f32 as Float>::MAX)),
121            D::Float64 => Some(Scalar::from(<f64 as Float>::MAX)),
122            _ => None,
123        }
124    }
125
126    pub fn min(&self) -> Option<Scalar> {
127        use DataType as D;
128        match self {
129            D::Int8 => Some(Scalar::from(<i8 as Integer>::MIN)),
130            D::Int16 => Some(Scalar::from(<i16 as Integer>::MIN)),
131            D::Int32 => Some(Scalar::from(<i32 as Integer>::MIN)),
132            D::Int64 => Some(Scalar::from(<i64 as Integer>::MIN)),
133            D::Int128 => Some(Scalar::from(<i128 as Integer>::MIN)),
134            D::UInt8 => Some(Scalar::from(<u8 as Integer>::MIN)),
135            D::UInt16 => Some(Scalar::from(<u16 as Integer>::MIN)),
136            D::UInt32 => Some(Scalar::from(<u32 as Integer>::MIN)),
137            D::UInt64 => Some(Scalar::from(<u64 as Integer>::MIN)),
138            D::UInt128 => Some(Scalar::from(<u128 as Integer>::MIN)),
139            D::Float32 => Some(Scalar::from(<f32 as Float>::MIN)),
140            D::Float64 => Some(Scalar::from(<f64 as Float>::MIN)),
141            _ => None,
142        }
143    }
144
145    pub fn primitive_bounds(&self) -> Option<(Scalar, Scalar)> {
146        match (self.min(), self.max()) {
147            (Some(min), Some(max)) => Some((min, max)),
148            _ => None,
149        }
150    }
151}
152
153impl From<String> for DataType {
154    fn from(value: String) -> Self {
155        match value.trim().to_lowercase().as_str() {
156            dtype_names::NULL => DataType::Null,
157
158            dtype_names::UINT8 => DataType::UInt8,
159            dtype_names::UINT16 => DataType::UInt16,
160            dtype_names::UINT32 => DataType::UInt32,
161            dtype_names::UINT64 => DataType::UInt64,
162            dtype_names::UINT128 => DataType::UInt128,
163
164            dtype_names::INT8 => DataType::Int8,
165            dtype_names::INT16 => DataType::Int16,
166            dtype_names::INT32 => DataType::Int32,
167            dtype_names::INT64 => DataType::Int64,
168            dtype_names::INT128 => DataType::Int128,
169
170            dtype_names::FLOAT32 => DataType::Float32,
171            dtype_names::FLOAT64 => DataType::Float64,
172
173            dtype_names::BOOLEAN => DataType::Boolean,
174
175            dtype_names::CHAR => DataType::Char,
176            dtype_names::STRING => DataType::String,
177
178            dtype_names::VEC => DataType::List(Box::new(DataType::Null)),
179            dtype_names::STRUCT => DataType::Struct(vec![]),
180
181            _ => panic!("Unknown data type: {}", value),
182        }
183    }
184}
185
186impl Display for DataType {
187    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188        match self {
189            DataType::Null => write!(f, "{}", dtype_names::NULL)?,
190
191            DataType::UInt8 => write!(f, "{}", dtype_names::UINT8)?,
192            DataType::UInt16 => write!(f, "{}", dtype_names::UINT16)?,
193            DataType::UInt32 => write!(f, "{}", dtype_names::UINT32)?,
194            DataType::UInt64 => write!(f, "{}", dtype_names::UINT64)?,
195            DataType::UInt128 => write!(f, "{}", dtype_names::UINT128)?,
196
197            DataType::Int8 => write!(f, "{}", dtype_names::INT8)?,
198            DataType::Int16 => write!(f, "{}", dtype_names::INT16)?,
199            DataType::Int32 => write!(f, "{}", dtype_names::INT32)?,
200            DataType::Int64 => write!(f, "{}", dtype_names::INT64)?,
201            DataType::Int128 => write!(f, "{}", dtype_names::INT128)?,
202
203            DataType::Float32 => write!(f, "{}", dtype_names::FLOAT32)?,
204            DataType::Float64 => write!(f, "{}", dtype_names::FLOAT64)?,
205
206            DataType::Duration => write!(f, "{}", dtype_names::DURATION)?,
207
208            DataType::Boolean => write!(f, "{}", dtype_names::BOOLEAN)?,
209
210            DataType::Char => write!(f, "{}", dtype_names::CHAR)?,
211            DataType::String => write!(f, "{}", dtype_names::STRING)?,
212
213            DataType::List(inner) => write!(f, "{}({})", dtype_names::VEC, inner)?,
214            DataType::Struct(vals) => write!(
215                f,
216                "struct({})",
217                vals.iter()
218                    .map(|f| format!("{}", f.name.clone()))
219                    .collect::<Vec<_>>()
220                    .join(", ")
221            )?,
222        };
223
224        Ok(())
225    }
226}