use std::error::Error;
use std::fmt::{Display, Formatter, Result as FmtResult};
use std::sync::Arc;
#[derive(Debug, Clone)]
pub enum ProviderCreateError {
Unavailable {
reason: String,
source: Option<Arc<dyn Error + Send + Sync + 'static>>,
},
Failed {
reason: String,
source: Option<Arc<dyn Error + Send + Sync + 'static>>,
},
}
impl ProviderCreateError {
#[inline]
pub fn unavailable(reason: &str) -> Self {
Self::Unavailable {
reason: reason.to_owned(),
source: None,
}
}
#[inline]
pub fn unavailable_with_source<E>(reason: &str, source: E) -> Self
where
E: Error + Send + Sync + 'static,
{
Self::Unavailable {
reason: reason.to_owned(),
source: Some(Arc::new(source)),
}
}
#[inline]
pub fn failed(reason: &str) -> Self {
Self::Failed {
reason: reason.to_owned(),
source: None,
}
}
#[inline]
pub fn failed_with_source<E>(reason: &str, source: E) -> Self
where
E: Error + Send + Sync + 'static,
{
Self::Failed {
reason: reason.to_owned(),
source: Some(Arc::new(source)),
}
}
#[inline]
pub fn reason(&self) -> &str {
match self {
Self::Unavailable { reason, .. } | Self::Failed { reason, .. } => reason,
}
}
#[inline]
pub(crate) fn is_unavailable(&self) -> bool {
matches!(self, Self::Unavailable { .. })
}
#[inline]
fn source_error(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Unavailable { source, .. } | Self::Failed { source, .. } => source
.as_deref()
.map(|source| source as &(dyn Error + 'static)),
}
}
}
impl Display for ProviderCreateError {
#[inline]
fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
match self {
Self::Unavailable { reason, .. } => {
write!(formatter, "provider is unavailable: {reason}")
}
Self::Failed { reason, .. } => {
write!(formatter, "provider failed to create service: {reason}")
}
}
}
}
impl Error for ProviderCreateError {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.source_error()
}
}