use std::{error::Error as StdError, fmt};
use thiserror::Error;
pub type BoxError = Box<dyn StdError + Send + Sync>;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum Capability {
ModelCatalog,
Balance,
}
impl fmt::Display for Capability {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = match self {
Self::ModelCatalog => "model catalog",
Self::Balance => "balance",
};
f.write_str(label)
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum BackendConstructError {
#[error("no backend registered for family '{family}'")]
UnknownFamily {
family: String,
},
#[error("failed to build {family} backend: {source}")]
Provider {
family: &'static str,
#[source]
source: BoxError,
},
}
impl BackendConstructError {
pub fn unknown_family(family: impl Into<String>) -> Self {
Self::UnknownFamily {
family: family.into(),
}
}
pub fn provider<E>(family: &'static str, source: E) -> Self
where
E: StdError + Send + Sync + 'static,
{
Self::Provider {
family,
source: Box::new(source),
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum CapabilityError {
#[error("{family} does not support {capability}")]
Unsupported {
family: &'static str,
capability: Capability,
},
#[error("{family} has not implemented {capability}")]
Unimplemented {
family: &'static str,
capability: Capability,
},
#[error("{family} cannot currently provide {capability}: {message}")]
Unavailable {
family: &'static str,
capability: Capability,
message: String,
},
}
impl CapabilityError {
pub fn unsupported(family: &'static str, capability: Capability) -> Self {
Self::Unsupported { family, capability }
}
pub fn unimplemented(family: &'static str, capability: Capability) -> Self {
Self::Unimplemented { family, capability }
}
pub fn unavailable(
family: &'static str,
capability: Capability,
message: impl Into<String>,
) -> Self {
Self::Unavailable {
family,
capability,
message: message.into(),
}
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum BackendError {
#[error("invalid request: {0}")]
InvalidRequest(String),
#[error("serialization error: {source}")]
Serialization {
#[source]
source: serde_json::Error,
},
#[error("{family} backend error: {source}")]
Provider {
family: &'static str,
#[source]
source: BoxError,
},
}
impl BackendError {
pub fn invalid_request(message: impl Into<String>) -> Self {
Self::InvalidRequest(message.into())
}
pub fn serialization(source: serde_json::Error) -> Self {
Self::Serialization { source }
}
pub fn provider<E>(family: &'static str, source: E) -> Self
where
E: StdError + Send + Sync + 'static,
{
Self::Provider {
family,
source: Box::new(source),
}
}
}