1use crate::EigenError;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct Eigenvector<T> {
6 coordinates: Vec<T>,
7}
8
9impl<T> Eigenvector<T> {
10 pub fn new(coordinates: Vec<T>) -> Result<Self, EigenError> {
16 Self::try_new(coordinates)
17 }
18
19 pub fn try_new(coordinates: Vec<T>) -> Result<Self, EigenError> {
25 if coordinates.is_empty() {
26 Err(EigenError::EmptyEigenvector)
27 } else {
28 Ok(Self { coordinates })
29 }
30 }
31
32 pub fn from_coordinates(coordinates: Vec<T>) -> Result<Self, EigenError> {
38 Self::try_new(coordinates)
39 }
40
41 #[must_use]
43 pub fn coordinates(&self) -> &[T] {
44 &self.coordinates
45 }
46
47 #[must_use]
49 pub fn into_inner(self) -> Vec<T> {
50 self.coordinates
51 }
52
53 #[must_use]
55 pub const fn dimension(&self) -> usize {
56 self.coordinates.len()
57 }
58}
59
60impl<T> AsRef<[T]> for Eigenvector<T> {
61 fn as_ref(&self) -> &[T] {
62 self.coordinates()
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::Eigenvector;
69 use crate::EigenError;
70
71 #[test]
72 fn constructs_an_eigenvector_and_exposes_coordinates() {
73 let vector = Eigenvector::from_coordinates(vec![1_i32, 0, -1]).expect("valid eigenvector");
74
75 assert_eq!(vector.coordinates(), &[1, 0, -1]);
76 assert_eq!(vector.dimension(), 3);
77 }
78
79 #[test]
80 fn rejects_empty_coordinates() {
81 assert_eq!(
82 Eigenvector::<i32>::new(vec![]),
83 Err(EigenError::EmptyEigenvector)
84 );
85 }
86}