nabled_embeddings/
error.rs1use nabled_core::errors::{IntoNabledError, NabledError, ShapeError};
4use nabled_linalg::matrix::MatrixError;
5use nabled_linalg::vector::VectorError;
6use nabled_ml::pca::PCAError;
7use thiserror::Error;
8
9#[derive(Debug, Clone, PartialEq, Eq, Error)]
11pub enum EmbeddingError {
12 #[error("input cannot be empty")]
14 EmptyInput,
15 #[error("input dimensions are incompatible")]
17 DimensionMismatch,
18 #[error("operation is undefined for zero-norm vectors")]
20 ZeroNorm,
21 #[error("invalid input: {0}")]
23 InvalidInput(String),
24 #[error("decomposition failed")]
26 DecompositionFailed,
27}
28
29impl From<VectorError> for EmbeddingError {
30 fn from(value: VectorError) -> Self {
31 match value {
32 VectorError::EmptyInput => EmbeddingError::EmptyInput,
33 VectorError::DimensionMismatch => EmbeddingError::DimensionMismatch,
34 VectorError::ZeroNorm => EmbeddingError::ZeroNorm,
35 }
36 }
37}
38
39impl From<MatrixError> for EmbeddingError {
40 fn from(value: MatrixError) -> Self {
41 match value {
42 MatrixError::EmptyInput => EmbeddingError::EmptyInput,
43 MatrixError::DimensionMismatch => EmbeddingError::DimensionMismatch,
44 }
45 }
46}
47
48impl From<PCAError> for EmbeddingError {
49 fn from(value: PCAError) -> Self {
50 match value {
51 PCAError::EmptyMatrix => EmbeddingError::EmptyInput,
52 PCAError::InvalidInput(message) => EmbeddingError::InvalidInput(message),
53 PCAError::DecompositionFailed => EmbeddingError::DecompositionFailed,
54 }
55 }
56}
57
58impl IntoNabledError for EmbeddingError {
59 fn into_nabled_error(self) -> NabledError {
60 match self {
61 EmbeddingError::EmptyInput => NabledError::Shape(ShapeError::EmptyInput),
62 EmbeddingError::DimensionMismatch => NabledError::Shape(ShapeError::DimensionMismatch),
63 EmbeddingError::ZeroNorm => NabledError::InvalidInput(
64 "operation is undefined for zero-norm vectors".to_string(),
65 ),
66 EmbeddingError::InvalidInput(message) => NabledError::InvalidInput(message),
67 EmbeddingError::DecompositionFailed => NabledError::ConvergenceFailed,
68 }
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn vector_error_maps_to_embedding_error() {
78 assert_eq!(EmbeddingError::from(VectorError::EmptyInput), EmbeddingError::EmptyInput);
79 assert_eq!(
80 EmbeddingError::from(VectorError::DimensionMismatch),
81 EmbeddingError::DimensionMismatch
82 );
83 assert_eq!(EmbeddingError::from(VectorError::ZeroNorm), EmbeddingError::ZeroNorm);
84 }
85
86 #[test]
87 fn matrix_error_maps_to_embedding_error() {
88 assert_eq!(EmbeddingError::from(MatrixError::EmptyInput), EmbeddingError::EmptyInput);
89 assert_eq!(
90 EmbeddingError::from(MatrixError::DimensionMismatch),
91 EmbeddingError::DimensionMismatch
92 );
93 }
94
95 #[test]
96 fn pca_error_maps_to_embedding_error() {
97 assert_eq!(EmbeddingError::from(PCAError::EmptyMatrix), EmbeddingError::EmptyInput);
98 assert_eq!(
99 EmbeddingError::from(PCAError::InvalidInput("x".to_string())),
100 EmbeddingError::InvalidInput("x".to_string())
101 );
102 assert_eq!(
103 EmbeddingError::from(PCAError::DecompositionFailed),
104 EmbeddingError::DecompositionFailed
105 );
106 }
107
108 #[test]
109 fn embedding_error_maps_to_shared_taxonomy() {
110 assert!(matches!(
111 EmbeddingError::EmptyInput.into_nabled_error(),
112 NabledError::Shape(ShapeError::EmptyInput)
113 ));
114 assert!(matches!(
115 EmbeddingError::DimensionMismatch.into_nabled_error(),
116 NabledError::Shape(ShapeError::DimensionMismatch)
117 ));
118 assert!(matches!(
119 EmbeddingError::ZeroNorm.into_nabled_error(),
120 NabledError::InvalidInput(_)
121 ));
122 assert!(matches!(
123 EmbeddingError::InvalidInput("x".to_string()).into_nabled_error(),
124 NabledError::InvalidInput(_)
125 ));
126 assert!(matches!(
127 EmbeddingError::DecompositionFailed.into_nabled_error(),
128 NabledError::ConvergenceFailed
129 ));
130 }
131
132 #[test]
133 fn embedding_error_displays_messages() {
134 assert_eq!(EmbeddingError::EmptyInput.to_string(), "input cannot be empty");
135 assert_eq!(
136 EmbeddingError::DimensionMismatch.to_string(),
137 "input dimensions are incompatible"
138 );
139 assert_eq!(
140 EmbeddingError::ZeroNorm.to_string(),
141 "operation is undefined for zero-norm vectors"
142 );
143 assert_eq!(
144 EmbeddingError::InvalidInput("oops".to_string()).to_string(),
145 "invalid input: oops"
146 );
147 assert_eq!(EmbeddingError::DecompositionFailed.to_string(), "decomposition failed");
148 }
149}