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}