Skip to main content

cml/
error.rs

1//! CML engine error type.
2//!
3//! The engine reads from a borrowed [`NodeReader`](crate::NodeReader) substrate
4//! and folds structure over it; its only failure modes are a propagated reader
5//! error and a corrupted-on-read invariant violation. Multi-algorithm and epoch
6//! errors (unknown algorithm, frozen, malformed timeline) are the `polydigest`
7//! combinator's concern, not the single-algorithm engine's.
8
9use std::fmt;
10
11/// CML engine error, parameterised by the [`NodeReader`](crate::NodeReader)
12/// backend's error type.
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum Error<E> {
15    /// An error wrapper around the read backend's error type.
16    Read(E),
17    /// A stored node or frontier read back malformed (wrong digest width, a
18    /// missing node in an active range, or a frontier-stack underflow during the
19    /// carry). The `alg_id` names which algorithm's view the engine was driving.
20    Corrupted {
21        /// The algorithm ID the engine was driving when the invariant broke.
22        alg_id: u64,
23        /// Why the read-back is corrupt.
24        reason: String,
25    },
26}
27
28impl<E: fmt::Display> fmt::Display for Error<E> {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        match self {
31            Self::Read(e) => write!(f, "read error: {e}"),
32            Self::Corrupted { alg_id, reason } => {
33                write!(f, "corrupted state for algorithm {alg_id}: {reason}")
34            },
35        }
36    }
37}
38
39impl<E: std::error::Error + 'static> std::error::Error for Error<E> {
40    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
41        match self {
42            Self::Read(e) => Some(e),
43            Self::Corrupted { .. } => None,
44        }
45    }
46}
47
48/// A specialized `Result` alias for the CML engine.
49pub type Result<T, E> = std::result::Result<T, Error<E>>;