plotpy/
as_vector.rs

1/// Defines a trait to handle Vector-like data
2///
3/// # Example
4///
5/// ```
6/// use plotpy::AsVector;
7///
8/// fn sum<'a, T, U>(array: &'a T) -> f64
9/// where
10///     T: AsVector<'a, U>,
11///     U: 'a + Into<f64>,
12/// {
13///     let mut res = 0.0;
14///     let m = array.vec_size();
15///     for i in 0..m {
16///         res += array.vec_at(i).into();
17///     }
18///     res
19/// }
20///
21/// // heap-allocated 1D array (vector)
22/// let x = vec![1.0, 2.0, 3.0];
23/// assert_eq!(sum(&x), 6.0);
24///
25/// // heap-allocated 1D array (slice)
26/// let y: &[f64] = &[10.0, 20.0, 30.0];
27/// assert_eq!(sum(&y), 60.0);
28///
29/// // stack-allocated (fixed-size) 2D array
30/// let z = [100.0, 200.0, 300.0];
31/// assert_eq!(sum(&z), 600.0);
32/// ```
33pub trait AsVector<'a, U: 'a> {
34    /// Returns the size of the vector
35    fn vec_size(&self) -> usize;
36
37    /// Returns the value at index i
38    fn vec_at(&self, i: usize) -> U;
39}
40
41/// Defines a heap-allocated 1D array (vector)
42impl<'a, U: 'a> AsVector<'a, U> for Vec<U>
43where
44    U: 'a + Copy,
45{
46    fn vec_size(&self) -> usize {
47        self.len()
48    }
49    fn vec_at(&self, i: usize) -> U {
50        self[i]
51    }
52}
53
54/// Defines a heap-allocated 1D array (slice)
55impl<'a, U> AsVector<'a, U> for &'a [U]
56where
57    U: 'a + Copy,
58{
59    fn vec_size(&self) -> usize {
60        self.len()
61    }
62    fn vec_at(&self, i: usize) -> U {
63        self[i]
64    }
65}
66
67/// Defines a stack-allocated (fixed-size) 1D array
68impl<'a, U, const M: usize> AsVector<'a, U> for [U; M]
69where
70    U: 'a + Copy,
71{
72    fn vec_size(&self) -> usize {
73        self.len()
74    }
75    fn vec_at(&self, i: usize) -> U {
76        self[i]
77    }
78}
79
80////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
81
82#[cfg(test)]
83mod tests {
84    use super::AsVector;
85    use std::fmt::Write;
86
87    fn vector_str<'a, T, U>(array: &'a T) -> String
88    where
89        T: AsVector<'a, U>,
90        U: 'a + std::fmt::Display,
91    {
92        let mut buf = String::new();
93        let m = array.vec_size();
94        for i in 0..m {
95            write!(&mut buf, "{},", array.vec_at(i)).unwrap();
96        }
97        write!(&mut buf, "\n").unwrap();
98        buf
99    }
100
101    #[test]
102    fn as_vector_works() {
103        // heap-allocated 1D array (vector)
104        let x = vec![1.0, 2.0, 3.0];
105        assert_eq!(vector_str(&x), "1,2,3,\n");
106
107        // heap-allocated 1D array (slice)
108        let y: &[f64] = &[10.0, 20.0, 30.0];
109        assert_eq!(vector_str(&y), "10,20,30,\n");
110
111        // stack-allocated (fixed-size) 2D array
112        let z = [100.0, 200.0, 300.0];
113        assert_eq!(vector_str(&z), "100,200,300,\n");
114    }
115}