api_keys_simplified/
error.rs1use thiserror::Error;
2
3#[derive(Debug, Error)]
9pub enum Error {
10 #[error("Invalid input")]
12 InvalidFormat,
13
14 #[error(transparent)]
16 Config(#[from] ConfigError),
17
18 #[error("Operation failed")]
27 OperationFailed(
28 #[source]
29 #[from]
30 OperationError,
31 ),
32}
33
34#[derive(Debug, Error)]
36pub enum ConfigError {
37 #[error("Prefix must be between 1 and 10 characters")]
38 InvalidPrefixLength,
39
40 #[error("Prefix must contain only alphanumeric characters or underscores")]
41 InvalidPrefixCharacters,
42
43 #[error("Prefix must not contain {0} substring")]
44 InvalidPrefixSubstring(String),
45
46 #[error("String must not be empty")]
47 EmptyString,
48
49 #[error("Entropy must be at least 16 bytes (128 bits)")]
50 EntropyTooLow,
51
52 #[error("Entropy cannot exceed 64 bytes (512 bits)")]
53 EntropyTooHigh,
54
55 #[error("Invalid Argon2 parameters")]
56 InvalidHashParams,
57}
58
59#[derive(Debug, Error)]
61pub enum OperationError {
62 #[error("Key generation failed: {0}")]
63 Generation(String),
64
65 #[error("Hashing failed: {0}")]
66 Hashing(String),
67
68 #[error("Verification failed: {0}")]
69 Verification(String),
70}
71
72pub type Result<T> = std::result::Result<T, Error>;
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn test_display_is_generic() {
80 let err =
81 Error::OperationFailed(OperationError::Hashing("detailed salt error".to_string()));
82 assert_eq!(err.to_string(), "Operation failed");
84
85 let debug_str = format!("{:?}", err);
87 assert!(debug_str.contains("Hashing"));
88 assert!(debug_str.contains("salt"));
89 }
90
91 #[test]
92 fn test_error_chaining() {
93 let err = Error::OperationFailed(OperationError::Verification(
94 "argon2 param error".to_string(),
95 ));
96 if let Error::OperationFailed(source) = err {
98 assert!(source.to_string().contains("argon2"));
99 }
100 }
101
102 #[test]
103 fn test_format_errors_are_generic() {
104 let err = Error::InvalidFormat;
105 assert_eq!(err.to_string(), "Invalid input");
106 }
107
108 #[test]
109 fn test_config_errors_are_specific() {
110 let err = Error::Config(ConfigError::EntropyTooLow);
111 assert_eq!(
112 err.to_string(),
113 "Entropy must be at least 16 bytes (128 bits)"
114 );
115
116 let err = Error::Config(ConfigError::InvalidPrefixLength);
117 assert_eq!(
118 err.to_string(),
119 "Prefix must be between 1 and 10 characters"
120 );
121 }
122
123 #[test]
124 fn test_config_error_conversion() {
125 let config_err = ConfigError::EmptyString;
127 let err: Error = config_err.into();
128 assert_eq!(err.to_string(), "String must not be empty");
129 }
130}