array_object/
misc.rs

1use crate::error::ArrayObjectError;
2use crate::ArrayObject;
3
4pub(crate) trait Product {
5    fn product(&self) -> u64;
6}
7
8impl Product for Vec<u64> {
9    fn product(&self) -> u64 {
10        self.iter().product::<u64>()
11    }
12}
13
14/// Concatenates ArrayObjects.
15///
16/// ```
17/// use array_object::{ArrayObject, TryConcat};
18/// let mut objs = vec![];
19/// for _ in 0..8 {
20///     let temp: ArrayObject = vec![0i32, 1, 2, 3].into();
21///     objs.push(temp);
22/// }
23/// let obj = objs.try_concat().unwrap();
24/// ```
25pub trait TryConcat {
26    /// Concatenates ArrayObjects of the same type, size and shape, and create an ArrayObject of one higher dimension.
27    fn try_concat(self) -> Result<ArrayObject, ArrayObjectError>;
28}
29
30impl TryConcat for Vec<ArrayObject> {
31    fn try_concat(self) -> Result<ArrayObject, ArrayObjectError> {
32        if self[0].shape.len() > 14 {
33            return Err(ArrayObjectError::TooLargeDimension(self[0].shape.len() + 1));
34        }
35        let shape_orig = self[0].shape.clone();
36        let datatype = self[0].datatype.clone();
37        let datasize = self[0].datasize();
38
39        let mut shape = shape_orig.clone();
40        shape.insert(0, self.len() as u64);
41
42        let mut data = vec![];
43        for mut v in self.into_iter() {
44            if shape_orig == v.shape && datatype == v.datatype && datasize == v.datasize() {
45                data.append(&mut v.data);
46            } else {
47                return Err(ArrayObjectError::ConcatShapeMismatch);
48            }
49        }
50        Ok(ArrayObject {
51            data,
52            shape,
53            datatype,
54        })
55    }
56}
57
58/// A macro to save the data into a file. If the file exists, this will overwrite the existing file.
59///
60/// ```
61/// use array_object::*;
62/// let data = vec![1f64, 2.2, -1.1, 5.6];
63/// export_obj!("testdata.bin", data.clone());
64/// ```
65#[macro_export]
66macro_rules! export_obj {
67    ($path:literal,$x:expr) => {{
68        use array_object::Pack;
69        let obj: array_object::ArrayObject = $x.try_into().unwrap();
70        let data = obj.pack();
71        std::fs::write($path, data).unwrap();
72    }};
73}
74
75/// A macro to load the data from a file.
76///
77/// ```
78/// use array_object::*;
79/// let restored: Vec<f64> = import_obj!("testdata.bin");
80/// ```
81#[macro_export]
82macro_rules! import_obj {
83    ($path:literal) => {{
84        use array_object::Unpack;
85        let data = std::fs::read($path).unwrap();
86        let obj = array_object::ArrayObject::unpack(data).unwrap();
87        obj.try_into().unwrap()
88    }};
89}