Skip to main content

miden_node_utils/
lib.rs

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