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::Boolean => 0x0E,
133 Type::Float4 => 0x01,
134 Type::Float8 => 0x02,
135 Type::Int1 => 0x03,
136 Type::Int2 => 0x04,
137 Type::Int4 => 0x05,
138 Type::Int8 => 0x06,
139 Type::Int16 => 0x07,
140 Type::Utf8 => 0x08,
141 Type::Uint1 => 0x09,
142 Type::Uint2 => 0x0A,
143 Type::Uint4 => 0x0B,
144 Type::Uint8 => 0x0C,
145 Type::Uint16 => 0x0D,
146 Type::Date => 0x0F,
147 Type::DateTime => 0x10,
148 Type::Time => 0x11,
149 Type::Duration => 0x12,
150 Type::RowNumber => 0x13,
151 Type::IdentityId => 0x17,
152 Type::Uuid4 => 0x14,
153 Type::Uuid7 => 0x15,
154 Type::Blob => 0x16,
155 Type::Int => 0x18,
156 Type::Uint => 0x1A,
157 Type::Decimal {
158 ..
159 } => 0x19,
160 Type::Undefined => 0x00,
161 Type::Any => 0x1B,
162 }
163 }
164}
165
166impl Type {
167 pub fn from_u8(value: u8) -> Self {
168 match value {
169 0x00 => Type::Undefined,
170 0x01 => Type::Float4,
171 0x02 => Type::Float8,
172 0x03 => Type::Int1,
173 0x04 => Type::Int2,
174 0x05 => Type::Int4,
175 0x06 => Type::Int8,
176 0x07 => Type::Int16,
177 0x08 => Type::Utf8,
178 0x09 => Type::Uint1,
179 0x0A => Type::Uint2,
180 0x0B => Type::Uint4,
181 0x0C => Type::Uint8,
182 0x0D => Type::Uint16,
183 0x0E => Type::Boolean,
184 0x0F => Type::Date,
185 0x10 => Type::DateTime,
186 0x11 => Type::Time,
187 0x12 => Type::Duration,
188 0x13 => Type::RowNumber,
189 0x14 => Type::Uuid4,
190 0x15 => Type::Uuid7,
191 0x16 => Type::Blob,
192 0x17 => Type::IdentityId,
193 0x18 => Type::Int,
194 0x1A => Type::Uint,
195 0x19 => Type::Decimal,
196 0x1B => 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}