1use std::fmt;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
5pub enum Type {
6 Unsigned,
8 Signed,
10 Float,
12 Boolean,
14 Date,
16 DateTime,
18 NULL,
20 #[default]
22 Text,
23}
24
25impl fmt::Display for Type {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 match self {
28 Type::Unsigned => write!(f, "Unsigned"),
29 Type::Signed => write!(f, "Signed"),
30 Type::Float => write!(f, "Float"),
31 Type::Boolean => write!(f, "Boolean"),
32 Type::Date => write!(f, "Date"),
33 Type::DateTime => write!(f, "DateTime"),
34 Type::NULL => write!(f, "NULL"),
35 Type::Text => write!(f, "Text"),
36 }
37 }
38}
39
40impl Type {
41 pub const COUNT: usize = 8;
43
44 #[inline]
49 pub const fn as_index(&self) -> usize {
50 self.priority() as usize
51 }
52
53 #[inline]
55 pub const fn is_numeric(&self) -> bool {
56 matches!(self, Type::Unsigned | Type::Signed | Type::Float)
57 }
58
59 #[inline]
61 pub const fn is_temporal(&self) -> bool {
62 matches!(self, Type::Date | Type::DateTime)
63 }
64
65 pub const fn priority(&self) -> u8 {
68 match self {
69 Type::NULL => 0,
70 Type::Boolean => 1,
71 Type::Unsigned => 2,
72 Type::Signed => 3,
73 Type::Float => 4,
74 Type::Date => 5,
75 Type::DateTime => 6,
76 Type::Text => 7,
77 }
78 }
79
80 pub fn merge(self, other: Type) -> Type {
82 if self == other {
83 return self;
84 }
85
86 if self == Type::NULL {
88 return other;
89 }
90 if other == Type::NULL {
91 return self;
92 }
93
94 match (self, other) {
96 (Type::Unsigned, Type::Signed) | (Type::Signed, Type::Unsigned) => Type::Signed,
97 (Type::Unsigned, Type::Float)
98 | (Type::Float, Type::Unsigned)
99 | (Type::Signed, Type::Float)
100 | (Type::Float, Type::Signed) => Type::Float,
101 (Type::Date, Type::DateTime) | (Type::DateTime, Type::Date) => Type::DateTime,
102 _ => Type::Text,
104 }
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 #[test]
113 fn test_type_merge() {
114 assert_eq!(Type::Unsigned.merge(Type::Unsigned), Type::Unsigned);
115 assert_eq!(Type::Unsigned.merge(Type::Signed), Type::Signed);
116 assert_eq!(Type::Unsigned.merge(Type::Float), Type::Float);
117 assert_eq!(Type::NULL.merge(Type::Unsigned), Type::Unsigned);
118 assert_eq!(Type::Date.merge(Type::DateTime), Type::DateTime);
119 assert_eq!(Type::Boolean.merge(Type::Text), Type::Text);
120 }
121}