1use std::fmt;
4
5#[derive(Debug, Clone, PartialEq)]
7pub enum DataType {
8 Boolean,
10 Int8,
12 Int16,
14 Int32,
16 Int64,
18 UInt8,
20 UInt16,
22 UInt32,
24 UInt64,
26 Float32,
28 Float64,
30 Utf8,
32 Binary,
34 Timestamp,
36 Quaternion,
38 Tensor4D,
40 Complex64,
42 Spinor,
44}
45
46impl fmt::Display for DataType {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 match self {
49 DataType::Boolean => write!(f, "Boolean"),
50 DataType::Int8 => write!(f, "Int8"),
51 DataType::Int16 => write!(f, "Int16"),
52 DataType::Int32 => write!(f, "Int32"),
53 DataType::Int64 => write!(f, "Int64"),
54 DataType::UInt8 => write!(f, "UInt8"),
55 DataType::UInt16 => write!(f, "UInt16"),
56 DataType::UInt32 => write!(f, "UInt32"),
57 DataType::UInt64 => write!(f, "UInt64"),
58 DataType::Float32 => write!(f, "Float32"),
59 DataType::Float64 => write!(f, "Float64"),
60 DataType::Utf8 => write!(f, "Utf8"),
61 DataType::Binary => write!(f, "Binary"),
62 DataType::Timestamp => write!(f, "Timestamp"),
63 DataType::Quaternion => write!(f, "Quaternion"),
64 DataType::Tensor4D => write!(f, "Tensor4D"),
65 DataType::Complex64 => write!(f, "Complex64"),
66 DataType::Spinor => write!(f, "Spinor"),
67 }
68 }
69}
70
71#[derive(Debug, Clone, PartialEq)]
73pub struct Field {
74 name: String,
75 data_type: DataType,
76 nullable: bool,
77}
78
79impl Field {
80 pub fn new(name: impl Into<String>, data_type: DataType) -> Self {
82 Self {
83 name: name.into(),
84 data_type,
85 nullable: true,
86 }
87 }
88
89 pub fn new_non_nullable(name: impl Into<String>, data_type: DataType) -> Self {
91 Self {
92 name: name.into(),
93 data_type,
94 nullable: false,
95 }
96 }
97
98 pub fn name(&self) -> &str {
100 &self.name
101 }
102
103 pub fn data_type(&self) -> &DataType {
105 &self.data_type
106 }
107
108 pub fn is_nullable(&self) -> bool {
110 self.nullable
111 }
112}
113
114#[derive(Debug, Clone, PartialEq)]
116pub struct Schema {
117 fields: Vec<Field>,
118}
119
120impl Schema {
121 pub fn new(fields: Vec<Field>) -> Self {
123 Self { fields }
124 }
125
126 pub fn num_fields(&self) -> usize {
128 self.fields.len()
129 }
130
131 pub fn field(&self, index: usize) -> Option<&Field> {
133 self.fields.get(index)
134 }
135
136 pub fn field_by_name(&self, name: &str) -> Option<&Field> {
138 self.fields.iter().find(|f| f.name() == name)
139 }
140
141 pub fn fields(&self) -> &[Field] {
143 &self.fields
144 }
145
146 pub fn index_of(&self, name: &str) -> Option<usize> {
148 self.fields.iter().position(|f| f.name() == name)
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155
156 #[test]
157 fn test_field_creation() {
158 let field = Field::new("id", DataType::Int64);
159 assert_eq!(field.name(), "id");
160 assert_eq!(field.data_type(), &DataType::Int64);
161 assert!(field.is_nullable());
162 }
163
164 #[test]
165 fn test_non_nullable_field() {
166 let field = Field::new_non_nullable("id", DataType::Int64);
167 assert!(!field.is_nullable());
168 }
169
170 #[test]
171 fn test_schema_creation() {
172 let schema = Schema::new(vec![
173 Field::new("id", DataType::Int64),
174 Field::new("value", DataType::Float64),
175 ]);
176
177 assert_eq!(schema.num_fields(), 2);
178 assert_eq!(schema.field(0).unwrap().name(), "id");
179 assert_eq!(schema.field(1).unwrap().name(), "value");
180 }
181
182 #[test]
183 fn test_schema_field_by_name() {
184 let schema = Schema::new(vec![
185 Field::new("id", DataType::Int64),
186 Field::new("value", DataType::Float64),
187 ]);
188
189 let field = schema.field_by_name("value").unwrap();
190 assert_eq!(field.data_type(), &DataType::Float64);
191 }
192
193 #[test]
194 fn test_schema_index_of() {
195 let schema = Schema::new(vec![
196 Field::new("id", DataType::Int64),
197 Field::new("value", DataType::Float64),
198 ]);
199
200 assert_eq!(schema.index_of("id"), Some(0));
201 assert_eq!(schema.index_of("value"), Some(1));
202 assert_eq!(schema.index_of("unknown"), None);
203 }
204
205 #[test]
206 fn test_datatype_display() {
207 assert_eq!(DataType::Int64.to_string(), "Int64");
208 assert_eq!(DataType::Quaternion.to_string(), "Quaternion");
209 assert_eq!(DataType::Tensor4D.to_string(), "Tensor4D");
210 }
211}
212
213
214
215
216