1use std::fmt;
6
7#[derive(Debug, Clone)]
11pub enum TranslationError {
12 Config(String),
14
15 Network(String),
17
18 Api(String),
20
21 Parse(String),
23
24 RateLimit,
26}
27
28impl fmt::Display for TranslationError {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 TranslationError::Config(msg) => write!(f, "Configuration error: {}", msg),
32 TranslationError::Network(msg) => write!(f, "Network error: {}", msg),
33 TranslationError::Api(msg) => write!(f, "API error: {}", msg),
34 TranslationError::Parse(msg) => write!(f, "Parse error: {}", msg),
35 TranslationError::RateLimit => write!(f, "Rate limit exceeded"),
36 }
37 }
38}
39
40impl std::error::Error for TranslationError {}
41
42impl From<reqwest::Error> for TranslationError {
43 fn from(error: reqwest::Error) -> Self {
44 if error.is_timeout() {
45 TranslationError::Network("Request timeout".to_string())
46 } else if error.is_connect() {
47 TranslationError::Network("Connection failed".to_string())
48 } else {
49 TranslationError::Network(error.to_string())
50 }
51 }
52}
53
54impl From<String> for TranslationError {
55 fn from(error: String) -> Self {
56 TranslationError::Api(error)
57 }
58}
59
60impl From<&str> for TranslationError {
61 fn from(error: &str) -> Self {
62 TranslationError::Api(error.to_string())
63 }
64}
65
66pub type TranslationResult<T> = std::result::Result<T, TranslationError>;
68
69impl TranslationError {
71 pub fn is_retryable(&self) -> bool {
72 matches!(
73 self,
74 TranslationError::Network(_) | TranslationError::RateLimit
75 )
76 }
77
78 pub fn retry_delay_ms(&self) -> Option<u64> {
80 match self {
81 TranslationError::Network(_) => Some(1000), TranslationError::RateLimit => Some(5000), _ => None,
84 }
85 }
86}