array_object/convert/
into_real.rs1use crate::adaptor::*;
2use crate::error::ArrayObjectError;
3use crate::storage::*;
4
5macro_rules! into_float {
6 ($($ty:tt),*) => {
7 $(
8 impl TryFrom<ArrayObject> for $ty {
9 type Error = ArrayObjectError;
10 fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
11 if !val.shape.is_empty() || val.datatype != DataType::Real {
12 return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
13 }
14 match val.data.len() {
15 4 => {
16 let data = f32::from_le_bytes(val.data.try_into().unwrap()) as $ty;
17 Ok(data)
18 }
19 8 => {
20 #[cfg(not(feature = "allow_float_down_convert"))]
21 if size_of::<$ty>() < 8 {
22 return Err(ArrayObjectError::LossyConversion);
23 }
24 let data = f64::from_le_bytes(val.data.try_into().unwrap()) as $ty;
25 Ok(data)
26 }
27 _ => {panic!();}
28 }
29 }
30 }
31 impl TryFrom<ArrayObject> for VecShape<$ty> {
32 type Error = ArrayObjectError;
33 fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
34 if val.shape.is_empty() || val.datatype != DataType::Real {
35 return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
36 }
37 let len = val.len();
38 if len == 0 {
39 return Ok(VecShape(vec![], val.shape));
40 }
41 match val.data.len() / len {
42 4 => {
43 let data = val.data.chunks(4).map(|b| f32::from_le_bytes(b.try_into().unwrap()) as $ty).collect();
44 Ok(VecShape(data, val.shape))
45 }
46 8 => {
47 #[cfg(not(feature = "allow_float_down_convert"))]
48 if size_of::<$ty>() < 8 {
49 return Err(ArrayObjectError::LossyConversion);
50 }
51 let data = val.data.chunks(8).map(|b| f64::from_le_bytes(b.try_into().unwrap()) as $ty).collect();
52 Ok(VecShape(data, val.shape))
53 }
54 _ => {panic!();}
55 }
56 }
57 }
58 impl TryFrom<ArrayObject> for Vec<$ty> {
59 type Error = ArrayObjectError;
60 fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
61 if val.shape.len() != 1 {
62 return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
63 }
64 let VecShape::<$ty>(data, _) = val.try_into()?;
65 Ok(data)
66 }
67 }
68 impl<const N: usize> TryFrom<ArrayObject> for [$ty; N] {
69 type Error = ArrayObjectError;
70 fn try_from(val: ArrayObject) -> Result<Self, Self::Error> {
71 if val.len() != N {
72 return Err(ArrayObjectError::WrongDataType(val.datatype, val.shape.len()));
73 }
74 let data: Vec<$ty> = val.try_into()?;
75 Ok(data.try_into().unwrap())
76 }
77 }
78 )*
79 };
80}
81
82into_float!(f32, f64);