1#[derive(Debug, thiserror::Error)]
2pub enum TokenFoldError {
3 #[error("invalid input: {0}")]
4 InvalidInput(String),
5 #[error("safety violation: {0}")]
6 SafetyViolation(String),
7 #[error("redaction failed: {0}")]
8 RedactionFailed(String),
9 #[error("estimator error: {0}")]
10 EstimatorError(String),
11 #[error("config error: {0}")]
12 ConfigError(String),
13 #[error("internal error: {0}")]
14 InternalError(String),
15 #[error("io error: {0}")]
16 Io(#[from] std::io::Error),
17}
18
19impl TokenFoldError {
20 pub fn exit_code(&self) -> i32 {
27 match self {
28 TokenFoldError::InvalidInput(_) => 2,
29 TokenFoldError::SafetyViolation(_) | TokenFoldError::RedactionFailed(_) => 3,
30 TokenFoldError::EstimatorError(_) => 4,
31 TokenFoldError::ConfigError(_) => 5,
32 TokenFoldError::InternalError(_) | TokenFoldError::Io(_) => 6,
33 }
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn exit_codes_match_error_taxonomy_table() {
43 assert_eq!(TokenFoldError::InvalidInput("x".into()).exit_code(), 2);
44 assert_eq!(TokenFoldError::SafetyViolation("x".into()).exit_code(), 3);
45 assert_eq!(TokenFoldError::RedactionFailed("x".into()).exit_code(), 3);
46 assert_eq!(TokenFoldError::EstimatorError("x".into()).exit_code(), 4);
47 assert_eq!(TokenFoldError::ConfigError("x".into()).exit_code(), 5);
48 assert_eq!(TokenFoldError::InternalError("x".into()).exit_code(), 6);
49 let io_err = TokenFoldError::from(std::io::Error::other("x"));
50 assert_eq!(io_err.exit_code(), 6);
51 }
52}