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