sane_array/
data.rs

1use ndarray::ArrayD;
2use quickcheck::{Arbitrary, Gen};
3
4/// SANE [supported data types](https://github.com/considerate/sane#data-types)
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub enum DataType {
7    F32,
8    I32,
9    U32,
10    F64,
11    I64,
12    U64,
13    I8,
14    U8,
15}
16
17impl Arbitrary for DataType {
18    fn arbitrary(gen: &mut Gen) -> Self {
19        use DataType::*;
20        let options = [F32, I32, U32, F64, I64, U64, I8, U8];
21        gen.choose(&options).unwrap().clone()
22    }
23}
24
25/// Parse a SANE-encoded u8 into the corresponding [`DataType`].
26pub fn parse_data_type(code: u8) -> Result<DataType, u8> {
27    match code {
28        0 => Ok(DataType::F32),
29        1 => Ok(DataType::I32),
30        2 => Ok(DataType::U32),
31        3 => Ok(DataType::F64),
32        4 => Ok(DataType::I64),
33        5 => Ok(DataType::U64),
34        6 => Ok(DataType::I8),
35        7 => Ok(DataType::U8),
36        n => Err(n),
37    }
38}
39
40/// Get the `u8` SANE-encoding of a [`DataType`].
41pub fn data_type_code(data_type: DataType) -> u8 {
42    match data_type {
43        DataType::F32 => 0,
44        DataType::I32 => 1,
45        DataType::U32 => 2,
46        DataType::F64 => 3,
47        DataType::I64 => 4,
48        DataType::U64 => 5,
49        DataType::I8 => 6,
50        DataType::U8 => 7,
51    }
52}
53
54/// A Sane array is an array with dynamic shape and elements of one of the [supported data
55/// types](https://github.com/considerate/sane#data-types)
56#[derive(Debug, Clone, PartialEq)]
57pub enum Sane {
58    ArrayF32(ArrayD<f32>),
59    ArrayI32(ArrayD<i32>),
60    ArrayU32(ArrayD<u32>),
61    ArrayF64(ArrayD<f64>),
62    ArrayI64(ArrayD<i64>),
63    ArrayU64(ArrayD<u64>),
64    ArrayI8(ArrayD<i8>),
65    ArrayU8(ArrayD<u8>),
66}
67
68
69/// The header of a SANE array, consisting of the shape, the data type and the length of the data
70/// in number of bytes
71pub struct Header {
72    pub shape: Vec<usize>,
73    pub data_type: DataType,
74    pub data_length: usize,
75}
76
77/// An element type with the [`SaneData`] trait defines which of the [supported data
78/// types](https://github.com/considerate/sane#data-types) it corresponds to
79pub trait SaneData: Copy {
80    fn sane_data_type() -> DataType;
81}
82
83impl SaneData for f32 {
84    fn sane_data_type()  -> DataType {
85        DataType::F32
86    }
87}
88
89impl SaneData for i32 {
90    fn sane_data_type()  -> DataType {
91        DataType::I32
92    }
93}
94
95impl SaneData for u32 {
96    fn sane_data_type()  -> DataType {
97        DataType::U32
98    }
99}
100
101impl SaneData for f64 {
102    fn sane_data_type()  -> DataType {
103        DataType::F64
104    }
105}
106
107impl SaneData for i64 {
108    fn sane_data_type()  -> DataType {
109        DataType::I64
110    }
111}
112
113impl SaneData for u64 {
114    fn sane_data_type()  -> DataType {
115        DataType::U64
116    }
117}
118
119impl SaneData for i8 {
120    fn sane_data_type()  -> DataType {
121        DataType::I8
122    }
123}
124
125impl SaneData for u8 {
126    fn sane_data_type()  -> DataType {
127        DataType::U8
128    }
129}
130
131#[cfg(test)]
132mod tests {
133    use super::{DataType, parse_data_type, data_type_code};
134    use quickcheck::quickcheck;
135    quickcheck! {
136        fn prop_data_type_round(data_type: DataType) -> bool {
137            Ok(data_type.clone()) == parse_data_type(data_type_code(data_type))
138        }
139    }
140}