use std::fmt::{Debug, Display, Formatter};
use crate::Class;
pub struct ClassificationMarker {
class: Class,
source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
}
impl ClassificationMarker {
pub const VALIDATION: Self = Self::with_class(Class::Validation);
pub const CORRUPTION: Self = Self::with_class(Class::Corruption);
pub const NOT_FOUND: Self = Self::with_class(Class::NotFound);
pub const RETRYABLE: Self = Self::with_class(Class::Retryable);
pub const ALLOCATION_LIMIT: Self =
Self::with_class(Class::ResourceExhaustion(ResourceExhaustionKind::AllocationLimit));
pub const ALLOCATION_FAILURE: Self =
Self::with_class(Class::ResourceExhaustion(ResourceExhaustionKind::AllocationFailure));
pub fn with_source(class: Class, source: impl std::error::Error + Send + Sync + 'static) -> Self {
ClassificationMarker {
class,
source: Some(Box::new(source)),
}
}
pub const fn with_class(class: Class) -> Self {
ClassificationMarker { class, source: None }
}
pub fn class(&self) -> Class {
self.class
}
}
impl Display for ClassificationMarker {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match &self.source {
Some(source) => Display::fmt(source, f),
None => Debug::fmt(&self.class, f),
}
}
}
impl Debug for ClassificationMarker {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match &self.source {
Some(source) => Debug::fmt(source, f),
None => Display::fmt(self, f),
}
}
}
impl std::error::Error for ClassificationMarker {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.source.as_deref().map(|source| source as _)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum ResourceExhaustionKind {
AllocationLimit,
AllocationFailure,
}