use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Code {
Authentication,
Quota,
RateLimit,
Transient,
Timeout,
Cancelled,
ProviderBudgetExceeded,
InvalidResult,
ResultCheckFailed,
ProviderError,
AgentError,
}
pub const BACKEND_STOPPED: &str = "BACKEND_STOPPED";
impl Code {
pub fn as_str(self) -> &'static str {
match self {
Self::Authentication => "AUTHENTICATION",
Self::Quota => "QUOTA",
Self::RateLimit => "RATE_LIMIT",
Self::Transient => "TRANSIENT",
Self::Timeout => "TIMEOUT",
Self::Cancelled => "CANCELLED",
Self::ProviderBudgetExceeded => "PROVIDER_BUDGET_EXCEEDED",
Self::InvalidResult => "INVALID_RESULT",
Self::ResultCheckFailed => "RESULT_CHECK_FAILED",
Self::ProviderError => "PROVIDER_ERROR",
Self::AgentError => "AGENT_ERROR",
}
}
pub fn retryable(self) -> bool {
matches!(self, Self::RateLimit | Self::Transient)
}
pub fn stops_backend(code: &str) -> bool {
code == Self::Authentication.as_str() || code == Self::Quota.as_str()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Failure {
pub code: Code,
pub message: String,
}
impl Failure {
pub fn new(code: Code, message: impl Into<String>) -> Self {
Self {
code,
message: message.into(),
}
}
pub fn cancelled() -> Self {
Self::new(Code::Cancelled, "Agent review was cancelled.")
}
pub fn timeout() -> Self {
Self::new(Code::Timeout, "Agent review timed out.")
}
}
impl From<String> for Failure {
fn from(message: String) -> Self {
Self::new(Code::AgentError, message)
}
}
impl fmt::Display for Failure {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(&self.message)
}
}