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 fn is_numeric(&self) -> bool {
43 matches!(self, Type::Unsigned | Type::Signed | Type::Float)
44 }
45
46 pub fn is_temporal(&self) -> bool {
48 matches!(self, Type::Date | Type::DateTime)
49 }
50
51 pub fn priority(&self) -> u8 {
54 match self {
55 Type::NULL => 0,
56 Type::Boolean => 1,
57 Type::Unsigned => 2,
58 Type::Signed => 3,
59 Type::Float => 4,
60 Type::Date => 5,
61 Type::DateTime => 6,
62 Type::Text => 7,
63 }
64 }
65
66 pub fn merge(self, other: Type) -> Type {
68 if self == other {
69 return self;
70 }
71
72 if self == Type::NULL {
74 return other;
75 }
76 if other == Type::NULL {
77 return self;
78 }
79
80 match (self, other) {
82 (Type::Unsigned, Type::Signed) | (Type::Signed, Type::Unsigned) => Type::Signed,
83 (Type::Unsigned, Type::Float)
84 | (Type::Float, Type::Unsigned)
85 | (Type::Signed, Type::Float)
86 | (Type::Float, Type::Signed) => Type::Float,
87 (Type::Date, Type::DateTime) | (Type::DateTime, Type::Date) => Type::DateTime,
88 _ => Type::Text,
90 }
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn test_type_merge() {
100 assert_eq!(Type::Unsigned.merge(Type::Unsigned), Type::Unsigned);
101 assert_eq!(Type::Unsigned.merge(Type::Signed), Type::Signed);
102 assert_eq!(Type::Unsigned.merge(Type::Float), Type::Float);
103 assert_eq!(Type::NULL.merge(Type::Unsigned), Type::Unsigned);
104 assert_eq!(Type::Date.merge(Type::DateTime), Type::DateTime);
105 assert_eq!(Type::Boolean.merge(Type::Text), Type::Text);
106 }
107}