use std::fmt;
use std::sync::Arc;
use thiserror::Error;
#[derive(Debug, Clone)]
pub struct ArcError(Arc<dyn std::error::Error + Send + Sync>);
impl ArcError {
pub(crate) fn new<E: std::error::Error + Send + Sync + 'static>(err: E) -> Self {
Self(Arc::new(err))
}
}
impl fmt::Display for ArcError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl std::error::Error for ArcError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(self.0.as_ref())
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Error)]
pub enum SchemaRegError {
#[error("schema registry error: {message}")]
Registry {
message: String,
#[source]
source: Option<ArcError>,
},
#[error("configuration error: {message}")]
Config {
message: String,
},
#[error("wire format error: {0}")]
WireFormat(String),
#[error("invalid state: {0}")]
InvalidState(String),
#[error("not supported: {0}")]
NotSupported(String),
}
impl SchemaRegError {
#[cold]
pub fn registry(message: impl Into<String>) -> Self {
Self::Registry {
message: message.into(),
source: None,
}
}
#[cold]
pub fn registry_with_source<E: std::error::Error + Send + Sync + 'static>(
message: impl Into<String>,
source: E,
) -> Self {
Self::Registry {
message: message.into(),
source: Some(ArcError::new(source)),
}
}
#[cold]
pub fn config(message: impl Into<String>) -> Self {
Self::Config {
message: message.into(),
}
}
#[cold]
pub fn wire_format(message: impl Into<String>) -> Self {
Self::WireFormat(message.into())
}
#[cold]
pub fn invalid_state(message: impl Into<String>) -> Self {
Self::InvalidState(message.into())
}
#[cold]
pub fn not_supported(message: impl Into<String>) -> Self {
Self::NotSupported(message.into())
}
#[must_use]
pub fn is_registry_error(&self) -> bool {
matches!(self, Self::Registry { .. })
}
#[must_use]
pub fn is_config_error(&self) -> bool {
matches!(self, Self::Config { .. })
}
#[must_use]
pub fn is_wire_format_error(&self) -> bool {
matches!(self, Self::WireFormat(_))
}
#[must_use]
pub fn is_not_supported(&self) -> bool {
matches!(self, Self::NotSupported(_))
}
#[must_use]
pub fn is_not_found(&self) -> bool {
match self {
Self::Registry { message, .. } => {
message.contains("(error code 404")
|| message.contains("Subject not found")
|| message.contains("Version not found")
|| message.contains("Schema not found")
}
_ => false,
}
}
}
pub type Result<T> = std::result::Result<T, SchemaRegError>;