use std::error::Error;
use std::fmt::{
Display,
Formatter,
Result as FmtResult,
};
use crate::{
ProviderCreateError,
ProviderName,
ProviderRegistryError,
};
#[derive(Debug, Clone)]
pub enum ProviderFailure {
UnknownProvider {
name: ProviderName,
},
Unavailable {
name: ProviderName,
source: ProviderCreateError,
},
CreateFailed {
name: ProviderName,
source: ProviderCreateError,
},
}
impl ProviderFailure {
#[inline]
pub fn unknown(name: &str) -> Result<Self, ProviderRegistryError> {
Ok(Self::unknown_name(ProviderName::new(name)?))
}
#[inline]
pub fn unavailable(name: &str, reason: &str) -> Result<Self, ProviderRegistryError> {
Self::unavailable_from_error(name, ProviderCreateError::unavailable(reason))
}
#[inline]
pub fn create_failed(name: &str, reason: &str) -> Result<Self, ProviderRegistryError> {
Self::create_failed_from_error(name, ProviderCreateError::failed(reason))
}
#[inline]
pub fn unavailable_from_error(
name: &str,
source: ProviderCreateError,
) -> Result<Self, ProviderRegistryError> {
Ok(Self::unavailable_error(ProviderName::new(name)?, source))
}
#[inline]
pub fn create_failed_from_error(
name: &str,
source: ProviderCreateError,
) -> Result<Self, ProviderRegistryError> {
Ok(Self::create_failed_error(ProviderName::new(name)?, source))
}
#[inline]
pub fn name(&self) -> &str {
self.provider_name().as_str()
}
#[inline]
pub fn provider_name(&self) -> &ProviderName {
match self {
Self::UnknownProvider { name }
| Self::Unavailable { name, .. }
| Self::CreateFailed { name, .. } => name,
}
}
#[inline]
pub(crate) fn unknown_name(name: ProviderName) -> Self {
Self::UnknownProvider { name }
}
#[inline]
pub(crate) fn unavailable_name(name: ProviderName, reason: &str) -> Self {
Self::unavailable_error(name, ProviderCreateError::unavailable(reason))
}
#[inline]
pub(crate) fn unavailable_error(name: ProviderName, source: ProviderCreateError) -> Self {
Self::Unavailable { name, source }
}
#[inline]
pub(crate) fn create_failed_error(name: ProviderName, source: ProviderCreateError) -> Self {
Self::CreateFailed { name, source }
}
}
impl Display for ProviderFailure {
#[inline]
fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
match self {
Self::UnknownProvider { name } => {
write!(formatter, "unknown provider: {name}")
}
Self::Unavailable { name, source } => {
write!(
formatter,
"provider '{name}' is unavailable: {}",
source.reason(),
)
}
Self::CreateFailed { name, source } => {
write!(
formatter,
"provider '{name}' failed to create service: {}",
source.reason(),
)
}
}
}
}
impl Error for ProviderFailure {
#[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::UnknownProvider { .. } => None,
Self::Unavailable { source, .. } | Self::CreateFailed { source, .. } => Some(source),
}
}
}