use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LogError<E> {
Storage(E),
UnknownAlgorithm(u64),
DuplicateAlgorithm(u64),
FrozenAlgorithm(u64),
AlgorithmActive(u64),
NoActiveAlgorithms,
IndexOutOfBounds {
index: u64,
tree_size: u64,
},
OrphanedMetadata(u64),
UnknownMetadata(u64),
CorruptedMetadata {
alg_id: u64,
reason: String,
},
MalformedSeal,
}
impl<E: fmt::Display> fmt::Display for LogError<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Storage(e) => write!(f, "storage error: {e}"),
Self::UnknownAlgorithm(id) => write!(f, "unknown algorithm: {id}"),
Self::DuplicateAlgorithm(id) => write!(f, "algorithm already registered: {id}"),
Self::FrozenAlgorithm(id) => write!(f, "algorithm is frozen: {id}"),
Self::AlgorithmActive(id) => write!(f, "algorithm is active: {id}"),
Self::NoActiveAlgorithms => write!(f, "no active algorithms"),
Self::IndexOutOfBounds { index, tree_size } => {
write!(f, "index {index} out of bounds for tree size {tree_size}")
},
Self::OrphanedMetadata(id) => {
write!(
f,
"algorithm {id} in storage metadata but no hasher provided"
)
},
Self::UnknownMetadata(id) => {
write!(
f,
"hasher provided for algorithm {id} with no stored metadata"
)
},
Self::CorruptedMetadata { alg_id, reason } => {
write!(f, "corrupted metadata for algorithm {alg_id}: {reason}")
},
Self::MalformedSeal => write!(f, "spine rejected the timeline while sealing"),
}
}
}
impl<E: std::error::Error + 'static> std::error::Error for LogError<E> {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Storage(e) => Some(e),
_ => None,
}
}
}
pub type LogResult<T, E> = std::result::Result<T, LogError<E>>;
impl<E> From<E> for LogError<E> {
fn from(err: E) -> Self {
Self::Storage(err)
}
}
impl<E> From<cml::Error<E>> for LogError<E> {
fn from(e: cml::Error<E>) -> Self {
match e {
cml::Error::Read(e) => Self::Storage(e),
cml::Error::Corrupted { alg_id, reason } => Self::CorruptedMetadata { alg_id, reason },
}
}
}