sys-rs 0.1.1

ptrace-based Linux system tool reimplementations: strace, gcov, addr2line, debugger
Documentation
use std::{
    backtrace::{Backtrace, BacktraceStatus},
    fmt, result,
};

/// A lightweight error wrapper used throughout the crate.
///
/// `Error` contains a human-readable error message and a captured
/// backtrace. It's convertible from types that implement `fmt::Display`.
pub struct Error {
    error: String,
    backtrace: Backtrace,
}

impl Error {
    fn new(error: String) -> Self {
        Self {
            error,
            backtrace: Backtrace::capture(),
        }
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.error)?;
        if self.backtrace.status() == BacktraceStatus::Captured {
            write!(f, "\nBacktrace:\n{}", self.backtrace)
        } else {
            Ok(())
        }
    }
}

impl<E: fmt::Display> From<E> for Error {
    fn from(e: E) -> Error {
        Error::new(e.to_string())
    }
}

/// Result type used across the crate, aliasing `std::result::Result` with
/// the crate's `Error` type.
pub type Result<T> = result::Result<T, Error>;

#[cfg(test)]
mod tests {
    use super::*;

    use ctor::ctor;

    #[ctor]
    fn init() {
        std::env::set_var("RUST_BACKTRACE", "1");
    }

    #[test]
    fn test_error_new() {
        let error = Error::new("Test error".to_string());
        assert_eq!(error.error, "Test error");
        assert!(error.backtrace.status() == BacktraceStatus::Captured);
    }

    #[test]
    fn test_error_from() {
        let error: Error = "Test error".to_string().into();
        assert_eq!(error.error, "Test error");
        assert!(error.backtrace.status() == BacktraceStatus::Captured);
    }

    #[test]
    fn test_error_debug() {
        let error = Error::new("Test error".to_string());
        let debug_output = format!("{:?}", error);
        assert!(debug_output.contains("Test error"));
        assert!(debug_output.contains("Backtrace"));
    }

    #[test]
    fn test_result_ok() {
        let result: Result<u32> = Ok(42);
        assert!(result.is_ok());
        assert_eq!(result.expect("Expected Ok value"), 42);
    }

    #[test]
    fn test_result_err() {
        let result: Result<u32> = Err("Test error".to_string().into());
        assert!(result.is_err());
        assert_eq!(result.unwrap_err().error, "Test error");
    }
}