1#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
6#[repr(u8)]
7pub enum PhysicalType {
8 Bool = 1,
9 Int64 = 2,
10 Int32 = 3,
11 Int16 = 4,
12 Int8 = 5,
13 UInt64 = 6,
14 UInt32 = 7,
15 UInt16 = 8,
16 UInt8 = 9,
17 Int128 = 10,
18 Float64 = 11,
19 Float32 = 12,
20 Interval = 13,
21 InternalId = 14,
22 String = 20,
23 List = 22,
24 Array = 23,
25 Struct = 24,
26}
27
28impl PhysicalType {
29 pub const fn fixed_size(&self) -> Option<usize> {
32 match self {
33 Self::Bool => Some(1),
34 Self::Int8 | Self::UInt8 => Some(1),
35 Self::Int16 | Self::UInt16 => Some(2),
36 Self::Int32 | Self::UInt32 | Self::Float32 => Some(4),
37 Self::Int64 | Self::UInt64 | Self::Float64 => Some(8),
38 Self::Int128 => Some(16),
39 Self::Interval => Some(16), Self::InternalId => Some(16), Self::String => None,
42 Self::List => None,
43 Self::Array => None,
44 Self::Struct => None,
45 }
46 }
47
48 pub const fn is_fixed_size(&self) -> bool {
50 self.fixed_size().is_some()
51 }
52}
53
54impl std::fmt::Display for PhysicalType {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 let name = match self {
57 Self::Bool => "BOOL",
58 Self::Int8 => "INT8",
59 Self::Int16 => "INT16",
60 Self::Int32 => "INT32",
61 Self::Int64 => "INT64",
62 Self::Int128 => "INT128",
63 Self::UInt8 => "UINT8",
64 Self::UInt16 => "UINT16",
65 Self::UInt32 => "UINT32",
66 Self::UInt64 => "UINT64",
67 Self::Float32 => "FLOAT",
68 Self::Float64 => "DOUBLE",
69 Self::Interval => "INTERVAL",
70 Self::InternalId => "INTERNAL_ID",
71 Self::String => "STRING",
72 Self::List => "LIST",
73 Self::Array => "ARRAY",
74 Self::Struct => "STRUCT",
75 };
76 write!(f, "{name}")
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn discriminant_values_match_cpp() {
86 assert_eq!(PhysicalType::Bool as u8, 1);
87 assert_eq!(PhysicalType::Int64 as u8, 2);
88 assert_eq!(PhysicalType::Int32 as u8, 3);
89 assert_eq!(PhysicalType::Int16 as u8, 4);
90 assert_eq!(PhysicalType::Int8 as u8, 5);
91 assert_eq!(PhysicalType::UInt64 as u8, 6);
92 assert_eq!(PhysicalType::UInt32 as u8, 7);
93 assert_eq!(PhysicalType::UInt16 as u8, 8);
94 assert_eq!(PhysicalType::UInt8 as u8, 9);
95 assert_eq!(PhysicalType::Int128 as u8, 10);
96 assert_eq!(PhysicalType::Float64 as u8, 11);
97 assert_eq!(PhysicalType::Float32 as u8, 12);
98 assert_eq!(PhysicalType::Interval as u8, 13);
99 assert_eq!(PhysicalType::InternalId as u8, 14);
100 assert_eq!(PhysicalType::String as u8, 20);
101 assert_eq!(PhysicalType::List as u8, 22);
102 assert_eq!(PhysicalType::Array as u8, 23);
103 assert_eq!(PhysicalType::Struct as u8, 24);
104 }
105
106 #[test]
107 fn fixed_sizes() {
108 assert_eq!(PhysicalType::Bool.fixed_size(), Some(1));
109 assert_eq!(PhysicalType::Int8.fixed_size(), Some(1));
110 assert_eq!(PhysicalType::Int16.fixed_size(), Some(2));
111 assert_eq!(PhysicalType::Int32.fixed_size(), Some(4));
112 assert_eq!(PhysicalType::Int64.fixed_size(), Some(8));
113 assert_eq!(PhysicalType::Int128.fixed_size(), Some(16));
114 assert_eq!(PhysicalType::Float32.fixed_size(), Some(4));
115 assert_eq!(PhysicalType::Float64.fixed_size(), Some(8));
116 assert_eq!(PhysicalType::Interval.fixed_size(), Some(16));
117 assert_eq!(PhysicalType::InternalId.fixed_size(), Some(16));
118 assert_eq!(PhysicalType::String.fixed_size(), None);
119 assert_eq!(PhysicalType::List.fixed_size(), None);
120 assert_eq!(PhysicalType::Array.fixed_size(), None);
121 assert_eq!(PhysicalType::Struct.fixed_size(), None);
122 }
123
124 #[test]
125 fn is_fixed_size() {
126 assert!(PhysicalType::Int64.is_fixed_size());
127 assert!(!PhysicalType::String.is_fixed_size());
128 assert!(!PhysicalType::List.is_fixed_size());
129 }
130
131 #[test]
132 fn enum_is_one_byte() {
133 assert_eq!(std::mem::size_of::<PhysicalType>(), 1);
134 }
135
136 #[test]
137 fn display() {
138 assert_eq!(PhysicalType::Bool.to_string(), "BOOL");
139 assert_eq!(PhysicalType::String.to_string(), "STRING");
140 assert_eq!(PhysicalType::InternalId.to_string(), "INTERNAL_ID");
141 }
142}