1use crate::tags::SampleFormat;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum DataType {
6 Bool,
8 UInt8,
10 UInt16,
12 UInt32,
14 UInt64,
16 Int8,
18 Int16,
20 Int32,
22 Int64,
24 Float32,
26 Float64,
28}
29
30impl DataType {
31 pub fn size(&self) -> usize {
43 match self {
44 DataType::Bool | DataType::UInt8 | DataType::Int8 => 1,
45 DataType::UInt16 | DataType::Int16 => 2,
46 DataType::UInt32 | DataType::Int32 | DataType::Float32 => 4,
47 DataType::UInt64 | DataType::Int64 | DataType::Float64 => 8,
48 }
49 }
50
51 pub(crate) fn from_tags(
60 sample_format: &[SampleFormat],
61 bits_per_sample: &[u16],
62 ) -> Option<Self> {
63 let first_format = sample_format.first()?;
65 let first_bits = bits_per_sample.first()?;
66
67 if !sample_format.iter().all(|f| f == first_format) {
69 return None;
70 }
71 if !bits_per_sample.iter().all(|b| b == first_bits) {
72 return None;
73 }
74
75 match (first_format, first_bits) {
76 (SampleFormat::Uint, 1) => Some(DataType::Bool),
77 (SampleFormat::Uint, 8) => Some(DataType::UInt8),
78 (SampleFormat::Uint, 16) => Some(DataType::UInt16),
79 (SampleFormat::Uint, 32) => Some(DataType::UInt32),
80 (SampleFormat::Uint, 64) => Some(DataType::UInt64),
81 (SampleFormat::Int, 8) => Some(DataType::Int8),
82 (SampleFormat::Int, 16) => Some(DataType::Int16),
83 (SampleFormat::Int, 32) => Some(DataType::Int32),
84 (SampleFormat::Int, 64) => Some(DataType::Int64),
85 (SampleFormat::Float, 32) => Some(DataType::Float32),
86 (SampleFormat::Float, 64) => Some(DataType::Float64),
87 _ => None,
89 }
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_from_tags_uint_types() {
99 assert_eq!(
100 DataType::from_tags(&[SampleFormat::Uint], &[1]),
101 Some(DataType::Bool),
102 "Uint 1-bit should be Bool"
103 );
104 assert_eq!(
105 DataType::from_tags(&[SampleFormat::Uint], &[8]),
106 Some(DataType::UInt8),
107 "Uint 8-bit should be UInt8"
108 );
109 assert_eq!(
110 DataType::from_tags(&[SampleFormat::Uint], &[16]),
111 Some(DataType::UInt16),
112 "Uint 16-bit should be UInt16"
113 );
114 assert_eq!(
115 DataType::from_tags(&[SampleFormat::Uint], &[32]),
116 Some(DataType::UInt32),
117 "Uint 32-bit should be UInt32"
118 );
119 assert_eq!(
120 DataType::from_tags(&[SampleFormat::Uint], &[64]),
121 Some(DataType::UInt64),
122 "Uint 64-bit should be UInt64"
123 );
124 }
125
126 #[test]
127 fn test_from_tags_int_types() {
128 assert_eq!(
129 DataType::from_tags(&[SampleFormat::Int], &[8]),
130 Some(DataType::Int8),
131 "Int 8-bit should be Int8"
132 );
133 assert_eq!(
134 DataType::from_tags(&[SampleFormat::Int], &[16]),
135 Some(DataType::Int16),
136 "Int 16-bit should be Int16"
137 );
138 assert_eq!(
139 DataType::from_tags(&[SampleFormat::Int], &[32]),
140 Some(DataType::Int32),
141 "Int 32-bit should be Int32"
142 );
143 assert_eq!(
144 DataType::from_tags(&[SampleFormat::Int], &[64]),
145 Some(DataType::Int64),
146 "Int 64-bit should be Int64"
147 );
148 }
149
150 #[test]
151 fn test_from_tags_float_types() {
152 assert_eq!(
153 DataType::from_tags(&[SampleFormat::Float], &[32]),
154 Some(DataType::Float32),
155 "Float 32-bit should be Float32"
156 );
157 assert_eq!(
158 DataType::from_tags(&[SampleFormat::Float], &[64]),
159 Some(DataType::Float64),
160 "Float 64-bit should be Float64"
161 );
162 }
163
164 #[test]
165 fn test_from_tags_rgb_consistent() {
166 assert_eq!(
168 DataType::from_tags(
169 &[SampleFormat::Uint, SampleFormat::Uint, SampleFormat::Uint],
170 &[8, 8, 8]
171 ),
172 Some(DataType::UInt8),
173 "RGB with consistent UInt8 should succeed"
174 );
175
176 assert_eq!(
178 DataType::from_tags(
179 &[SampleFormat::Uint, SampleFormat::Uint, SampleFormat::Uint],
180 &[16, 16, 16]
181 ),
182 Some(DataType::UInt16),
183 "RGB with consistent UInt16 should succeed"
184 );
185 }
186
187 #[test]
188 fn test_from_tags_inconsistent_format() {
189 assert_eq!(
191 DataType::from_tags(&[SampleFormat::Uint, SampleFormat::Int], &[8, 8]),
192 None,
193 "Inconsistent sample formats should return None"
194 );
195 }
196
197 #[test]
198 fn test_from_tags_inconsistent_bits() {
199 assert_eq!(
201 DataType::from_tags(&[SampleFormat::Uint, SampleFormat::Uint], &[8, 16]),
202 None,
203 "Inconsistent bit depths should return None"
204 );
205 }
206
207 #[test]
208 fn test_from_tags_empty_arrays() {
209 assert_eq!(
210 DataType::from_tags(&[], &[]),
211 None,
212 "Empty arrays should return None"
213 );
214 }
215
216 #[test]
217 fn test_from_tags_unsupported_bit_depth() {
218 assert_eq!(
220 DataType::from_tags(&[SampleFormat::Uint], &[12]),
221 None,
222 "Unsupported bit depth (12) should return None"
223 );
224 assert_eq!(
225 DataType::from_tags(&[SampleFormat::Uint], &[24]),
226 None,
227 "Unsupported bit depth (24) should return None"
228 );
229 }
230
231 #[test]
232 fn test_from_tags_unsupported_format() {
233 assert_eq!(
235 DataType::from_tags(&[SampleFormat::Void], &[8]),
236 None,
237 "Void format should return None"
238 );
239
240 assert_eq!(
242 DataType::from_tags(&[SampleFormat::Unknown(99)], &[8]),
243 None,
244 "Unknown format should return None"
245 );
246 }
247}