array_object/convert/
into_integer.rs

1use crate::adaptor::*;
2use crate::convert::zigzag::Zigzag;
3use crate::error::ArrayObjectError;
4use crate::storage::*;
5
6macro_rules! into_integer {
7    ($($ty:tt),*) => {
8        $(
9            impl TryFrom<ArrayObject> for $ty {
10                type Error = ArrayObjectError;
11                fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
12                    if !val.shape.is_empty() {
13                        return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
14                    }
15                    if val.datatype == DataType::UnsignedInteger {
16                        match val.data.len() {
17                            1 => {
18                                let data = u8::from_le_bytes(val.data.try_into().unwrap()).try_into()
19                                .or(Err(ArrayObjectError::IncompatibleConversion(false, 8)))?;
20                                Ok(data)
21                            }
22                            2 => {
23                                let data = u16::from_le_bytes(val.data.try_into().unwrap()).try_into()
24                                .or(Err(ArrayObjectError::IncompatibleConversion(false, 16)))?;
25                                Ok(data)
26                            }
27                            4 => {
28                                let data = u32::from_le_bytes(val.data.try_into().unwrap()).try_into()
29                                .or(Err(ArrayObjectError::IncompatibleConversion(false, 32)))?;
30                                Ok(data)
31                            }
32                            8 => {
33                                let data = u64::from_le_bytes(val.data.try_into().unwrap()).try_into()
34                                .or(Err(ArrayObjectError::IncompatibleConversion(false, 64)))?;
35                                Ok(data)
36                            }
37                            16 => {
38                                let data = u128::from_le_bytes(val.data.try_into().unwrap()).try_into()
39                                .or(Err(ArrayObjectError::IncompatibleConversion(false, 128)))?;
40                                Ok(data)
41                            }
42                            _ => {panic!();}
43                        }
44                    } else if val.datatype == DataType::SignedInteger {
45                        match val.data.len() {
46                            1 => {
47                                let data = i8::from_le_bytes(val.data.try_into().unwrap()).straight().try_into()
48                                .or(Err(ArrayObjectError::IncompatibleConversion(true, 8)))?;
49                                Ok(data)
50                            }
51                            2 => {
52                                let data = i16::from_le_bytes(val.data.try_into().unwrap()).straight().try_into()
53                                .or(Err(ArrayObjectError::IncompatibleConversion(true, 16)))?;
54                                Ok(data)
55                            }
56                            4 => {
57                                let data = i32::from_le_bytes(val.data.try_into().unwrap()).straight().try_into()
58                                .or(Err(ArrayObjectError::IncompatibleConversion(true, 32)))?;
59                                Ok(data)
60                            }
61                            8 => {
62                                let data = i64::from_le_bytes(val.data.try_into().unwrap()).straight().try_into()
63                                .or(Err(ArrayObjectError::IncompatibleConversion(true, 64)))?;
64                                Ok(data)
65                            }
66                            16 => {
67                                let data = i128::from_le_bytes(val.data.try_into().unwrap()).straight().try_into()
68                                .or(Err(ArrayObjectError::IncompatibleConversion(true, 128)))?;
69                                Ok(data)
70                            }
71                            _ => {panic!();}
72                        }
73                    } else {
74                        return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
75                    }
76                }
77            }
78            impl TryFrom<ArrayObject> for VecShape<$ty> {
79                type Error = ArrayObjectError;
80                fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
81                    if val.shape.is_empty() {
82                        return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
83                    }
84                    let len = val.len();
85                    if len == 0 {
86                        return Ok(VecShape(vec![], val.shape));
87                    }
88                    if val.datatype == DataType::UnsignedInteger {
89                        match val.data.len() / len {
90                            1 => {
91                                let mut data = Vec::with_capacity(len);
92                                for b in val.data.chunks(1) {
93                                    data.push(u8::from_le_bytes(b.try_into().unwrap()).try_into()
94                                    .or(Err(ArrayObjectError::IncompatibleConversion(false, 8)))?);
95                                }
96                                Ok(VecShape(data, val.shape))
97                            }
98                            2 => {
99                                let mut data = Vec::with_capacity(len);
100                                for b in val.data.chunks(2) {
101                                    data.push(u16::from_le_bytes(b.try_into().unwrap()).try_into()
102                                    .or(Err(ArrayObjectError::IncompatibleConversion(false, 16)))?);
103                                }
104                                Ok(VecShape(data, val.shape))
105                            }
106                            4 => {
107                                let mut data = Vec::with_capacity(len);
108                                for b in val.data.chunks(4) {
109                                    data.push(u32::from_le_bytes(b.try_into().unwrap()).try_into()
110                                    .or(Err(ArrayObjectError::IncompatibleConversion(false, 32)))?);
111                                }
112                                Ok(VecShape(data, val.shape))
113                            }
114                            8 => {
115                                let mut data = Vec::with_capacity(len);
116                                for b in val.data.chunks(8) {
117                                    data.push(u64::from_le_bytes(b.try_into().unwrap()).try_into()
118                                    .or(Err(ArrayObjectError::IncompatibleConversion(false, 64)))?);
119                                }
120                                Ok(VecShape(data, val.shape))
121                            }
122                            16 => {
123                                let mut data = Vec::with_capacity(len);
124                                for b in val.data.chunks(16) {
125                                    data.push(u128::from_le_bytes(b.try_into().unwrap()).try_into()
126                                    .or(Err(ArrayObjectError::IncompatibleConversion(false, 128)))?);
127                                }
128                                Ok(VecShape(data, val.shape))
129                            }
130                            _ => {panic!();}
131                        }
132                    } else if val.datatype == DataType::SignedInteger {
133                        match val.data.len() / len {
134                            1 => {
135                                let mut data = Vec::with_capacity(len);
136                                for b in val.data.chunks(1) {
137                                    data.push(i8::from_le_bytes(b.try_into().unwrap()).straight().try_into()
138                                    .or(Err(ArrayObjectError::IncompatibleConversion(true, 8)))?);
139                                }
140                                Ok(VecShape(data, val.shape))
141                            }
142                            2 => {
143                                let mut data = Vec::with_capacity(len);
144                                for b in val.data.chunks(2) {
145                                    data.push(i16::from_le_bytes(b.try_into().unwrap()).straight().try_into()
146                                    .or(Err(ArrayObjectError::IncompatibleConversion(true, 16)))?);
147                                }
148                                Ok(VecShape(data, val.shape))
149                            }
150                            4 => {
151                                let mut data = Vec::with_capacity(len);
152                                for b in val.data.chunks(4) {
153                                    data.push(i32::from_le_bytes(b.try_into().unwrap()).straight().try_into()
154                                    .or(Err(ArrayObjectError::IncompatibleConversion(true, 32)))?);
155                                }
156                                Ok(VecShape(data, val.shape))
157                            }
158                            8 => {
159                                let mut data = Vec::with_capacity(len);
160                                for b in val.data.chunks(8) {
161                                    data.push(i64::from_le_bytes(b.try_into().unwrap()).straight().try_into()
162                                    .or(Err(ArrayObjectError::IncompatibleConversion(true, 64)))?);
163                                }
164                                Ok(VecShape(data, val.shape))
165                            }
166                            16 => {
167                                let mut data = Vec::with_capacity(len);
168                                for b in val.data.chunks(16) {
169                                    data.push(i128::from_le_bytes(b.try_into().unwrap()).straight().try_into()
170                                    .or(Err(ArrayObjectError::IncompatibleConversion(true, 128)))?);
171                                }
172                                Ok(VecShape(data, val.shape))
173                            }
174                            _ => {panic!();}
175                        }
176                    } else {
177                        return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
178                    }
179                }
180            }
181            impl TryFrom<ArrayObject> for Vec<$ty> {
182                type Error = ArrayObjectError;
183                fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
184                    if val.shape.len() != 1 {
185                        return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
186                    }
187                    let VecShape::<$ty>(data, _) = val.try_into()?;
188                    Ok(data)
189                }
190            }
191            impl<const N: usize> TryFrom<ArrayObject> for [$ty; N] {
192                type Error = ArrayObjectError;
193                fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
194                    if val.len() != N {
195                        return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
196                    }
197                    let data: Vec<$ty> = val.try_into()?;
198                    Ok(data.try_into().unwrap())
199                }
200            }
201        )*
202    }
203}
204
205into_integer!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);