Skip to main content

sys_rs/
diag.rs

1use std::{
2    backtrace::{Backtrace, BacktraceStatus},
3    fmt, result,
4};
5
6/// A lightweight error wrapper used throughout the crate.
7///
8/// `Error` contains a human-readable error message and a captured
9/// backtrace. It's convertible from types that implement `fmt::Display`.
10pub struct Error {
11    error: String,
12    backtrace: Backtrace,
13}
14
15impl Error {
16    fn new(error: String) -> Self {
17        Self {
18            error,
19            backtrace: Backtrace::capture(),
20        }
21    }
22}
23
24impl fmt::Debug for Error {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        write!(f, "{}", self.error)?;
27        if self.backtrace.status() == BacktraceStatus::Captured {
28            write!(f, "\nBacktrace:\n{}", self.backtrace)
29        } else {
30            Ok(())
31        }
32    }
33}
34
35impl<E: fmt::Display> From<E> for Error {
36    fn from(e: E) -> Error {
37        Error::new(e.to_string())
38    }
39}
40
41/// Result type used across the crate, aliasing `std::result::Result` with
42/// the crate's `Error` type.
43pub type Result<T> = result::Result<T, Error>;
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    use ctor::ctor;
50
51    #[ctor]
52    fn init() {
53        std::env::set_var("RUST_BACKTRACE", "1");
54    }
55
56    #[test]
57    fn test_error_new() {
58        let error = Error::new("Test error".to_string());
59        assert_eq!(error.error, "Test error");
60        assert!(error.backtrace.status() == BacktraceStatus::Captured);
61    }
62
63    #[test]
64    fn test_error_from() {
65        let error: Error = "Test error".to_string().into();
66        assert_eq!(error.error, "Test error");
67        assert!(error.backtrace.status() == BacktraceStatus::Captured);
68    }
69
70    #[test]
71    fn test_error_debug() {
72        let error = Error::new("Test error".to_string());
73        let debug_output = format!("{:?}", error);
74        assert!(debug_output.contains("Test error"));
75        assert!(debug_output.contains("Backtrace"));
76    }
77
78    #[test]
79    fn test_result_ok() {
80        let result: Result<u32> = Ok(42);
81        assert!(result.is_ok());
82        assert_eq!(result.expect("Expected Ok value"), 42);
83    }
84
85    #[test]
86    fn test_result_err() {
87        let result: Result<u32> = Err("Test error".to_string().into());
88        assert!(result.is_err());
89        assert_eq!(result.unwrap_err().error, "Test error");
90    }
91}