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 {
22 match self {
23 TokenFoldError::InvalidInput(_) => 2,
24 TokenFoldError::SafetyViolation(_) | TokenFoldError::RedactionFailed(_) => 3,
25 TokenFoldError::EstimatorError(_) => 4,
26 TokenFoldError::ConfigError(_) => 5,
27 TokenFoldError::InternalError(_) | TokenFoldError::Io(_) => 6,
28 }
29 }
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35
36 #[test]
37 fn exit_codes_match_error_taxonomy_table() {
38 assert_eq!(TokenFoldError::InvalidInput("x".into()).exit_code(), 2);
39 assert_eq!(TokenFoldError::SafetyViolation("x".into()).exit_code(), 3);
40 assert_eq!(TokenFoldError::RedactionFailed("x".into()).exit_code(), 3);
41 assert_eq!(TokenFoldError::EstimatorError("x".into()).exit_code(), 4);
42 assert_eq!(TokenFoldError::ConfigError("x".into()).exit_code(), 5);
43 assert_eq!(TokenFoldError::InternalError("x".into()).exit_code(), 6);
44 let io_err = TokenFoldError::from(std::io::Error::other("x"));
45 assert_eq!(io_err.exit_code(), 6);
46 }
47}