use core::{any::type_name, fmt};
#[cfg(doc)]
use super::{PrunedStore, Store, StoreInner};
#[derive(Debug, Copy, Clone)]
pub enum StoreError<E> {
Internal(InternalStoreError),
External(E),
}
impl<E: fmt::Display> fmt::Display for StoreError<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
StoreError::Internal(error) => fmt::Display::fmt(error, f),
StoreError::External(error) => fmt::Display::fmt(error, f),
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct InternalStoreError {
kind: InternalStoreErrorKind,
}
impl InternalStoreError {
fn new(kind: InternalStoreErrorKind) -> Self {
Self { kind }
}
#[cold]
#[inline]
pub fn not_found() -> Self {
Self::new(InternalStoreErrorKind::EntityNotFound)
}
#[cold]
#[inline]
pub fn store_mismatch() -> Self {
Self::new(InternalStoreErrorKind::StoreMismatch)
}
#[cold]
#[inline]
pub fn restore_type_mismatch<T>() -> Self {
Self::new(InternalStoreErrorKind::RestoreTypeMismatch(
RestoreTypeMismatchError::new::<T>(),
))
}
}
impl fmt::Display for InternalStoreError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let message = match &self.kind {
InternalStoreErrorKind::RestoreTypeMismatch(error) => {
return fmt::Display::fmt(error, f);
}
InternalStoreErrorKind::StoreMismatch => "store owner mismatch",
InternalStoreErrorKind::EntityNotFound => "entity not found",
};
write!(f, "failed to resolve entity: {message}")
}
}
#[derive(Debug, Copy, Clone)]
enum InternalStoreErrorKind {
RestoreTypeMismatch(RestoreTypeMismatchError),
StoreMismatch,
EntityNotFound,
}
impl<E> StoreError<E> {
pub fn external(error: E) -> Self {
Self::External(error)
}
}
impl<E> From<InternalStoreError> for StoreError<E> {
fn from(error: InternalStoreError) -> Self {
Self::Internal(error)
}
}
#[derive(Debug, Copy, Clone)]
struct RestoreTypeMismatchError {
type_name: fn() -> &'static str,
}
impl RestoreTypeMismatchError {
pub fn new<T>() -> Self {
Self {
type_name: type_name::<T>,
}
}
}
impl fmt::Display for RestoreTypeMismatchError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"failed to unprune store due to type mismatch: {}",
(self.type_name)()
)
}
}