1use std::{
5 fmt::{Display, Formatter},
6 str::FromStr,
7};
8
9use serde::{Deserialize, Serialize};
10
11mod get;
12mod promote;
13
14pub use get::GetType;
15
16use crate::Value;
17
18#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
20pub enum Type {
21 Boolean,
23 Float4,
25 Float8,
27 Int1,
29 Int2,
31 Int4,
33 Int8,
35 Int16,
37 Utf8,
39 Uint1,
41 Uint2,
43 Uint4,
45 Uint8,
47 Uint16,
49 Date,
51 DateTime,
53 Time,
55 Duration,
57 RowNumber,
59 IdentityId,
61 Uuid4,
63 Uuid7,
65 Blob,
67 Int,
69 Uint,
71 Decimal,
73 Undefined,
75 Any,
77}
78
79impl Type {
80 pub fn is_number(&self) -> bool {
81 matches!(
82 self,
83 Type::Float4
84 | Type::Float8 | Type::Int1 | Type::Int2
85 | Type::Int4 | Type::Int8 | Type::Int16
86 | Type::Uint1 | Type::Uint2 | Type::Uint4
87 | Type::Uint8 | Type::Uint16 | Type::Int
88 | Type::Uint | Type::Decimal
89 )
90 }
91
92 pub fn is_bool(&self) -> bool {
93 matches!(self, Type::Boolean)
94 }
95
96 pub fn is_signed_integer(&self) -> bool {
97 matches!(self, Type::Int1 | Type::Int2 | Type::Int4 | Type::Int8 | Type::Int16 | Type::Int)
98 }
99
100 pub fn is_unsigned_integer(&self) -> bool {
101 matches!(self, Type::Uint1 | Type::Uint2 | Type::Uint4 | Type::Uint8 | Type::Uint16 | Type::Uint)
102 }
103
104 pub fn is_integer(&self) -> bool {
105 self.is_signed_integer() || self.is_unsigned_integer()
106 }
107
108 pub fn is_floating_point(&self) -> bool {
109 matches!(self, Type::Float4 | Type::Float8)
110 }
111
112 pub fn is_utf8(&self) -> bool {
113 matches!(self, Type::Utf8)
114 }
115
116 pub fn is_temporal(&self) -> bool {
117 matches!(self, Type::Date | Type::DateTime | Type::Time | Type::Duration)
118 }
119
120 pub fn is_uuid(&self) -> bool {
121 matches!(self, Type::Uuid4 | Type::Uuid7)
122 }
123
124 pub fn is_blob(&self) -> bool {
125 matches!(self, Type::Blob)
126 }
127}
128
129impl Type {
130 pub fn to_u8(&self) -> u8 {
131 match self {
132 Type::Undefined => 0,
133 Type::Float4 => 1,
134 Type::Float8 => 2,
135 Type::Int1 => 3,
136 Type::Int2 => 4,
137 Type::Int4 => 5,
138 Type::Int8 => 6,
139 Type::Int16 => 7,
140 Type::Utf8 => 8,
141 Type::Uint1 => 9,
142 Type::Uint2 => 10,
143 Type::Uint4 => 11,
144 Type::Uint8 => 12,
145 Type::Uint16 => 13,
146 Type::Boolean => 14,
147 Type::Date => 15,
148 Type::DateTime => 16,
149 Type::Time => 17,
150 Type::Duration => 18,
151 Type::RowNumber => 19,
152 Type::Uuid4 => 20,
153 Type::Uuid7 => 21,
154 Type::Blob => 22,
155 Type::IdentityId => 23,
156 Type::Int => 24,
157 Type::Decimal {
158 ..
159 } => 25,
160 Type::Uint => 26,
161 Type::Any => 27,
162 }
163 }
164}
165
166impl Type {
167 pub fn from_u8(value: u8) -> Self {
168 match value {
169 0 => Type::Undefined,
170 1 => Type::Float4,
171 2 => Type::Float8,
172 3 => Type::Int1,
173 4 => Type::Int2,
174 5 => Type::Int4,
175 6 => Type::Int8,
176 7 => Type::Int16,
177 8 => Type::Utf8,
178 9 => Type::Uint1,
179 10 => Type::Uint2,
180 11 => Type::Uint4,
181 12 => Type::Uint8,
182 13 => Type::Uint16,
183 14 => Type::Boolean,
184 15 => Type::Date,
185 16 => Type::DateTime,
186 17 => Type::Time,
187 18 => Type::Duration,
188 19 => Type::RowNumber,
189 20 => Type::Uuid4,
190 21 => Type::Uuid7,
191 22 => Type::Blob,
192 23 => Type::IdentityId,
193 24 => Type::Int,
194 25 => Type::Decimal,
195 26 => Type::Uint,
196 27 => Type::Any,
197 _ => unreachable!(),
198 }
199 }
200}
201
202impl Type {
203 pub fn size(&self) -> usize {
204 match self {
205 Type::Boolean => 1,
206 Type::Float4 => 4,
207 Type::Float8 => 8,
208 Type::Int1 => 1,
209 Type::Int2 => 2,
210 Type::Int4 => 4,
211 Type::Int8 => 8,
212 Type::Int16 => 16,
213 Type::Utf8 => 8, Type::Uint1 => 1,
215 Type::Uint2 => 2,
216 Type::Uint4 => 4,
217 Type::Uint8 => 8,
218 Type::Uint16 => 16,
219 Type::Date => 4,
220 Type::DateTime => 12, Type::Time => 8,
222 Type::Duration => 16, Type::RowNumber => 8,
225 Type::IdentityId => 16, Type::Uuid4 => 16,
227 Type::Uuid7 => 16,
228 Type::Blob => 8, Type::Int => 16, Type::Uint => 16, Type::Decimal {
234 ..
235 } => 16, Type::Undefined => 0,
238 Type::Any => 8, }
240 }
241
242 pub fn alignment(&self) -> usize {
243 match self {
244 Type::Boolean => 1,
245 Type::Float4 => 4,
246 Type::Float8 => 8,
247 Type::Int1 => 1,
248 Type::Int2 => 2,
249 Type::Int4 => 4,
250 Type::Int8 => 8,
251 Type::Int16 => 16,
252 Type::Utf8 => 4, Type::Uint1 => 1,
254 Type::Uint2 => 2,
255 Type::Uint4 => 4,
256 Type::Uint8 => 8,
257 Type::Uint16 => 16,
258 Type::Date => 4,
259 Type::DateTime => 8,
260 Type::Time => 8,
261 Type::Duration => 8,
262 Type::RowNumber => 8,
263 Type::IdentityId => 8, Type::Uuid4 => 8,
265 Type::Uuid7 => 8,
266 Type::Blob => 4, Type::Int => 16, Type::Uint => 16, Type::Decimal {
272 ..
273 } => 16, Type::Undefined => 0,
276 Type::Any => 8, }
278 }
279}
280
281impl Display for Type {
282 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
283 match self {
284 Type::Boolean => f.write_str("Boolean"),
285 Type::Float4 => f.write_str("Float4"),
286 Type::Float8 => f.write_str("Float8"),
287 Type::Int1 => f.write_str("Int1"),
288 Type::Int2 => f.write_str("Int2"),
289 Type::Int4 => f.write_str("Int4"),
290 Type::Int8 => f.write_str("Int8"),
291 Type::Int16 => f.write_str("Int16"),
292 Type::Utf8 => f.write_str("Utf8"),
293 Type::Uint1 => f.write_str("Uint1"),
294 Type::Uint2 => f.write_str("Uint2"),
295 Type::Uint4 => f.write_str("Uint4"),
296 Type::Uint8 => f.write_str("Uint8"),
297 Type::Uint16 => f.write_str("Uint16"),
298 Type::Date => f.write_str("Date"),
299 Type::DateTime => f.write_str("DateTime"),
300 Type::Time => f.write_str("Time"),
301 Type::Duration => f.write_str("Duration"),
302 Type::RowNumber => f.write_str("RowNumber"),
303 Type::IdentityId => f.write_str("IdentityId"),
304 Type::Uuid4 => f.write_str("Uuid4"),
305 Type::Uuid7 => f.write_str("Uuid7"),
306 Type::Blob => f.write_str("Blob"),
307 Type::Int => f.write_str("Int"),
308 Type::Uint => f.write_str("Uint"),
309 Type::Decimal => f.write_str("Decimal"),
310 Type::Undefined => f.write_str("Undefined"),
311 Type::Any => f.write_str("Any"),
312 }
313 }
314}
315
316impl From<&Value> for Type {
317 fn from(value: &Value) -> Self {
318 match value {
319 Value::Undefined => Type::Undefined,
320 Value::Boolean(_) => Type::Boolean,
321 Value::Float4(_) => Type::Float4,
322 Value::Float8(_) => Type::Float8,
323 Value::Int1(_) => Type::Int1,
324 Value::Int2(_) => Type::Int2,
325 Value::Int4(_) => Type::Int4,
326 Value::Int8(_) => Type::Int8,
327 Value::Int16(_) => Type::Int16,
328 Value::Utf8(_) => Type::Utf8,
329 Value::Uint1(_) => Type::Uint1,
330 Value::Uint2(_) => Type::Uint2,
331 Value::Uint4(_) => Type::Uint4,
332 Value::Uint8(_) => Type::Uint8,
333 Value::Uint16(_) => Type::Uint16,
334 Value::Date(_) => Type::Date,
335 Value::DateTime(_) => Type::DateTime,
336 Value::Time(_) => Type::Time,
337 Value::Duration(_) => Type::Duration,
338 Value::RowNumber(_) => Type::RowNumber,
339 Value::IdentityId(_) => Type::IdentityId,
340 Value::Uuid4(_) => Type::Uuid4,
341 Value::Uuid7(_) => Type::Uuid7,
342 Value::Blob(_) => Type::Blob,
343 Value::Int(_) => Type::Int,
344 Value::Uint(_) => Type::Uint,
345 Value::Decimal(_) => Type::Decimal,
346 Value::Any(_) => Type::Any,
347 }
348 }
349}
350
351impl FromStr for Type {
352 type Err = ();
353
354 fn from_str(s: &str) -> Result<Self, Self::Err> {
355 match s.to_uppercase().as_str() {
356 "BOOL" | "BOOLEAN" => Ok(Type::Boolean),
357 "FLOAT4" => Ok(Type::Float4),
358 "FLOAT8" => Ok(Type::Float8),
359 "INT1" => Ok(Type::Int1),
360 "INT2" => Ok(Type::Int2),
361 "INT4" => Ok(Type::Int4),
362 "INT8" => Ok(Type::Int8),
363 "INT16" => Ok(Type::Int16),
364 "UTF8" | "TEXT" => Ok(Type::Utf8),
365 "UINT1" => Ok(Type::Uint1),
366 "UINT2" => Ok(Type::Uint2),
367 "UINT4" => Ok(Type::Uint4),
368 "UINT8" => Ok(Type::Uint8),
369 "UINT16" => Ok(Type::Uint16),
370 "DATE" => Ok(Type::Date),
371 "DATETIME" => Ok(Type::DateTime),
372 "TIME" => Ok(Type::Time),
373 "DURATION" | "INTERVAL" => Ok(Type::Duration),
374 "ROWNUMBER" | "ROWID" => Ok(Type::RowNumber),
375 "IDENTITYID" | "IDENTITY_ID" => Ok(Type::IdentityId),
376 "UUID4" => Ok(Type::Uuid4),
377 "UUID7" => Ok(Type::Uuid7),
378 "BLOB" => Ok(Type::Blob),
379 "INT" => Ok(Type::Int),
380 "UINT" => Ok(Type::Uint),
381 "DECIMAL" => Ok(Type::Decimal),
382 "UNDEFINED" => Ok(Type::Undefined),
383 "ANY" => Ok(Type::Any),
384 _ => Err(()),
385 }
386 }
387}