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