use std::fmt;
#[derive(Debug, Clone)]
pub enum TranslationError {
Config(String),
Network(String),
Api(String),
Parse(String),
RateLimit,
}
impl fmt::Display for TranslationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TranslationError::Config(msg) => write!(f, "Configuration error: {}", msg),
TranslationError::Network(msg) => write!(f, "Network error: {}", msg),
TranslationError::Api(msg) => write!(f, "API error: {}", msg),
TranslationError::Parse(msg) => write!(f, "Parse error: {}", msg),
TranslationError::RateLimit => write!(f, "Rate limit exceeded"),
}
}
}
impl std::error::Error for TranslationError {}
impl From<reqwest::Error> for TranslationError {
fn from(error: reqwest::Error) -> Self {
if error.is_timeout() {
TranslationError::Network("Request timeout".to_string())
} else if error.is_connect() {
TranslationError::Network("Connection failed".to_string())
} else {
TranslationError::Network(error.to_string())
}
}
}
impl From<String> for TranslationError {
fn from(error: String) -> Self {
TranslationError::Api(error)
}
}
impl From<&str> for TranslationError {
fn from(error: &str) -> Self {
TranslationError::Api(error.to_string())
}
}
pub type TranslationResult<T> = std::result::Result<T, TranslationError>;
impl TranslationError {
pub fn is_retryable(&self) -> bool {
matches!(
self,
TranslationError::Network(_) | TranslationError::RateLimit
)
}
pub fn retry_delay_ms(&self) -> Option<u64> {
match self {
TranslationError::Network(_) => Some(1000), TranslationError::RateLimit => Some(5000), _ => None,
}
}
}