Skip to main content

miden_node_utils/
lib.rs

1pub mod block_cache;
2pub mod clap;
3pub mod cors;
4pub mod crypto;
5#[cfg(feature = "testing")]
6pub mod fee;
7pub mod formatting;
8pub mod fs;
9pub mod genesis;
10pub mod grpc;
11pub mod limiter;
12pub mod logging;
13pub mod lru_cache;
14pub mod panic;
15pub mod retry;
16pub mod shutdown;
17pub mod spawn;
18pub mod tasks;
19pub mod tracing;
20
21pub trait ErrorReport: std::error::Error {
22    /// Returns a string representation of the error and its source chain.
23    fn as_report(&self) -> String {
24        use std::fmt::Write;
25        let mut report = self.to_string();
26
27        // SAFETY: write! is suggested by clippy, and is trivially safe usage.
28        std::iter::successors(self.source(), |child| child.source())
29            .for_each(|source| write!(report, "\ncaused by: {source}").unwrap());
30
31        report
32    }
33
34    /// Creates a new root in the error chain and returns a string representation of the error and
35    /// its source chain.
36    fn as_report_context(&self, context: &'static str) -> String {
37        format!("{context}: \ncaused by: {}", self.as_report())
38    }
39}
40
41impl<T: std::error::Error> ErrorReport for T {}
42
43/// Extends nested results types, allowing them to be flattened.
44///
45/// Adapted from: <https://stackoverflow.com/a/77543839>
46pub trait FlattenResult<V, OuterError, InnerError>
47where
48    InnerError: Into<OuterError>,
49{
50    fn flatten_result(self) -> Result<V, OuterError>;
51}
52
53impl<V, OuterError, InnerError> FlattenResult<V, OuterError, InnerError>
54    for Result<Result<V, InnerError>, OuterError>
55where
56    OuterError: From<InnerError>,
57{
58    fn flatten_result(self) -> Result<V, OuterError> {
59        match self {
60            Ok(Ok(value)) => Ok(value),
61            Ok(Err(inner)) => Err(inner.into()),
62            Err(outer) => Err(outer),
63        }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use crate::ErrorReport;
70
71    #[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)]
72    pub enum TestSourceError {
73        #[error("source error")]
74        Source,
75    }
76
77    #[derive(thiserror::Error, Debug)]
78    pub enum TestError {
79        #[error("parent error")]
80        Parent(#[from] TestSourceError),
81    }
82
83    #[test]
84    fn as_report() {
85        let error = TestError::Parent(TestSourceError::Source);
86        assert_eq!("parent error\ncaused by: source error", error.as_report());
87    }
88
89    #[test]
90    fn as_report_context() {
91        let error = TestError::Parent(TestSourceError::Source);
92        assert_eq!(
93            "final error: \ncaused by: parent error\ncaused by: source error",
94            error.as_report_context("final error")
95        );
96    }
97}