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