use crate::tags::SampleFormat;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DataType {
Bool,
UInt8,
UInt16,
UInt32,
UInt64,
Int8,
Int16,
Int32,
Int64,
Float32,
Float64,
}
impl DataType {
pub fn size(&self) -> usize {
match self {
DataType::Bool | DataType::UInt8 | DataType::Int8 => 1,
DataType::UInt16 | DataType::Int16 => 2,
DataType::UInt32 | DataType::Int32 | DataType::Float32 => 4,
DataType::UInt64 | DataType::Int64 | DataType::Float64 => 8,
}
}
pub(crate) fn from_tags(
sample_format: &[SampleFormat],
bits_per_sample: &[u16],
) -> Option<Self> {
let first_format = sample_format.first()?;
let first_bits = bits_per_sample.first()?;
if !sample_format.iter().all(|f| f == first_format) {
return None;
}
if !bits_per_sample.iter().all(|b| b == first_bits) {
return None;
}
match (first_format, first_bits) {
(SampleFormat::Uint, 1) => Some(DataType::Bool),
(SampleFormat::Uint, 8) => Some(DataType::UInt8),
(SampleFormat::Uint, 16) => Some(DataType::UInt16),
(SampleFormat::Uint, 32) => Some(DataType::UInt32),
(SampleFormat::Uint, 64) => Some(DataType::UInt64),
(SampleFormat::Int, 8) => Some(DataType::Int8),
(SampleFormat::Int, 16) => Some(DataType::Int16),
(SampleFormat::Int, 32) => Some(DataType::Int32),
(SampleFormat::Int, 64) => Some(DataType::Int64),
(SampleFormat::Float, 32) => Some(DataType::Float32),
(SampleFormat::Float, 64) => Some(DataType::Float64),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_from_tags_uint_types() {
assert_eq!(
DataType::from_tags(&[SampleFormat::Uint], &[1]),
Some(DataType::Bool),
"Uint 1-bit should be Bool"
);
assert_eq!(
DataType::from_tags(&[SampleFormat::Uint], &[8]),
Some(DataType::UInt8),
"Uint 8-bit should be UInt8"
);
assert_eq!(
DataType::from_tags(&[SampleFormat::Uint], &[16]),
Some(DataType::UInt16),
"Uint 16-bit should be UInt16"
);
assert_eq!(
DataType::from_tags(&[SampleFormat::Uint], &[32]),
Some(DataType::UInt32),
"Uint 32-bit should be UInt32"
);
assert_eq!(
DataType::from_tags(&[SampleFormat::Uint], &[64]),
Some(DataType::UInt64),
"Uint 64-bit should be UInt64"
);
}
#[test]
fn test_from_tags_int_types() {
assert_eq!(
DataType::from_tags(&[SampleFormat::Int], &[8]),
Some(DataType::Int8),
"Int 8-bit should be Int8"
);
assert_eq!(
DataType::from_tags(&[SampleFormat::Int], &[16]),
Some(DataType::Int16),
"Int 16-bit should be Int16"
);
assert_eq!(
DataType::from_tags(&[SampleFormat::Int], &[32]),
Some(DataType::Int32),
"Int 32-bit should be Int32"
);
assert_eq!(
DataType::from_tags(&[SampleFormat::Int], &[64]),
Some(DataType::Int64),
"Int 64-bit should be Int64"
);
}
#[test]
fn test_from_tags_float_types() {
assert_eq!(
DataType::from_tags(&[SampleFormat::Float], &[32]),
Some(DataType::Float32),
"Float 32-bit should be Float32"
);
assert_eq!(
DataType::from_tags(&[SampleFormat::Float], &[64]),
Some(DataType::Float64),
"Float 64-bit should be Float64"
);
}
#[test]
fn test_from_tags_rgb_consistent() {
assert_eq!(
DataType::from_tags(
&[SampleFormat::Uint, SampleFormat::Uint, SampleFormat::Uint],
&[8, 8, 8]
),
Some(DataType::UInt8),
"RGB with consistent UInt8 should succeed"
);
assert_eq!(
DataType::from_tags(
&[SampleFormat::Uint, SampleFormat::Uint, SampleFormat::Uint],
&[16, 16, 16]
),
Some(DataType::UInt16),
"RGB with consistent UInt16 should succeed"
);
}
#[test]
fn test_from_tags_inconsistent_format() {
assert_eq!(
DataType::from_tags(&[SampleFormat::Uint, SampleFormat::Int], &[8, 8]),
None,
"Inconsistent sample formats should return None"
);
}
#[test]
fn test_from_tags_inconsistent_bits() {
assert_eq!(
DataType::from_tags(&[SampleFormat::Uint, SampleFormat::Uint], &[8, 16]),
None,
"Inconsistent bit depths should return None"
);
}
#[test]
fn test_from_tags_empty_arrays() {
assert_eq!(
DataType::from_tags(&[], &[]),
None,
"Empty arrays should return None"
);
}
#[test]
fn test_from_tags_unsupported_bit_depth() {
assert_eq!(
DataType::from_tags(&[SampleFormat::Uint], &[12]),
None,
"Unsupported bit depth (12) should return None"
);
assert_eq!(
DataType::from_tags(&[SampleFormat::Uint], &[24]),
None,
"Unsupported bit depth (24) should return None"
);
}
#[test]
fn test_from_tags_unsupported_format() {
assert_eq!(
DataType::from_tags(&[SampleFormat::Void], &[8]),
None,
"Void format should return None"
);
assert_eq!(
DataType::from_tags(&[SampleFormat::Unknown(99)], &[8]),
None,
"Unknown format should return None"
);
}
}