1use std::error::Error;
2
3#[derive(Debug, Clone, Copy, PartialEq)]
5pub enum Bitpix {
6 F64 = -64,
8
9 F32 = -32,
11
12 U8 = 8,
14
15 I16 = 16,
17
18 I32 = 32,
20}
21
22impl Bitpix {
23 pub fn byte_size(&self) -> usize {
25 match self {
26 Bitpix::F64 => 8,
27 Bitpix::F32 => 4,
28 Bitpix::U8 => 1,
29 Bitpix::I16 => 2,
30 Bitpix::I32 => 4,
31 }
32 }
33}
34
35impl Bitpix {
36 pub fn read_be(&self, bytes: &[u8]) -> Option<f64> {
42 fn take<const N: usize>(bytes: &[u8]) -> Option<[u8; N]> {
43 bytes.get(..N)?.try_into().ok()
44 }
45
46 match self {
47 Bitpix::F64 => Some(f64::from_be_bytes(take(bytes)?)),
48 Bitpix::F32 => Some(f32::from_be_bytes(take(bytes)?) as f64),
49 Bitpix::U8 => Some(*bytes.first()? as f64),
50 Bitpix::I16 => Some(i16::from_be_bytes(take(bytes)?) as f64),
51 Bitpix::I32 => Some(i32::from_be_bytes(take(bytes)?) as f64),
52 }
53 }
54
55 pub fn value_range(&self) -> Option<(f64, f64)> {
60 match self {
61 Bitpix::F64 | Bitpix::F32 => None,
62 Bitpix::U8 => Some((u8::MIN as f64, u8::MAX as f64)),
63 Bitpix::I16 => Some((i16::MIN as f64, i16::MAX as f64)),
64 Bitpix::I32 => Some((i32::MIN as f64, i32::MAX as f64)),
65 }
66 }
67}
68
69impl From<Bitpix> for i64 {
70 fn from(value: Bitpix) -> Self {
71 value as i64
72 }
73}
74
75impl TryFrom<i64> for Bitpix {
76 type Error = Box<dyn Error + Send + Sync>;
77
78 fn try_from(value: i64) -> Result<Self, Self::Error> {
79 match value {
80 -64 => Ok(Bitpix::F64),
81 -32 => Ok(Bitpix::F32),
82 8 => Ok(Bitpix::U8),
83 16 => Ok(Bitpix::I16),
84 32 => Ok(Bitpix::I32),
85 _ => Err(From::from(format!("Invalid bitpix value: {}", value))),
86 }
87 }
88}