use serde::{Deserialize, Serialize};
use thiserror::Error;
pub type ProviderResult<T> = Result<T, ProviderError>;
#[derive(Error, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ProviderError {
#[error("Authentication failed: {message}")]
Authentication { message: String },
#[error("Transport error: {message}")]
Transport { message: String },
#[error("Rate limit exceeded: {message}")]
RateLimit {
message: String,
retry_after: Option<u64>,
},
#[error("Malformed response: {message}")]
MalformedResponse { message: String },
#[error("Invalid request: {message}")]
InvalidRequest { message: String },
#[error("Model error: {message}")]
Model { message: String },
#[error("Provider error: {message}")]
General { message: String },
}
impl ProviderError {
pub fn auth<S: Into<String>>(message: S) -> Self {
Self::Authentication {
message: message.into(),
}
}
pub fn transport<S: Into<String>>(message: S) -> Self {
Self::Transport {
message: message.into(),
}
}
pub fn rate_limit<S: Into<String>>(message: S, retry_after: Option<u64>) -> Self {
Self::RateLimit {
message: message.into(),
retry_after,
}
}
pub fn malformed<S: Into<String>>(message: S) -> Self {
Self::MalformedResponse {
message: message.into(),
}
}
pub fn invalid_request<S: Into<String>>(message: S) -> Self {
Self::InvalidRequest {
message: message.into(),
}
}
pub fn model<S: Into<String>>(message: S) -> Self {
Self::Model {
message: message.into(),
}
}
pub fn general<S: Into<String>>(message: S) -> Self {
Self::General {
message: message.into(),
}
}
pub fn is_authentication(&self) -> bool {
matches!(self, Self::Authentication { .. })
}
pub fn is_rate_limit(&self) -> bool {
matches!(self, Self::RateLimit { .. })
}
pub fn is_transport(&self) -> bool {
matches!(self, Self::Transport { .. })
}
pub fn retry_after(&self) -> Option<u64> {
match self {
Self::RateLimit { retry_after, .. } => *retry_after,
_ => None,
}
}
}