miden_node_utils/
lib.rs

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