Skip to main content

miden_node_utils/
lib.rs

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