nullnet_liberror/
lib.rs

1use std::fmt::Display;
2
3#[derive(Debug)]
4/// General error type for Nullnet
5pub struct Error {
6    message: String,
7}
8
9impl Error {
10    #[must_use]
11    /// Returns the error message
12    pub fn to_str(&self) -> &str {
13        &self.message
14    }
15}
16
17/// Trait for logging and handling errors in a unified way
18pub trait ErrorHandler<T, E> {
19    /// Handle the error and log its location
20    #[allow(clippy::missing_errors_doc)]
21    fn handle_err(self, loc: Location) -> Result<T, Error>;
22}
23
24impl<T, E: Display> ErrorHandler<T, E> for Result<T, E> {
25    fn handle_err(self, location: Location) -> Result<T, Error> {
26        self.map_err(|e| {
27            log::error!("[{}:{}] {e}", location.file, location.line);
28            Error {
29                message: e.to_string(),
30            }
31        })
32    }
33}
34
35/// Struct to store the location in the code (file and line)
36pub struct Location {
37    pub file: &'static str,
38    pub line: u32,
39}
40
41#[macro_export]
42/// Macro to get the current location in the code (file and line)
43macro_rules! location {
44    () => {
45        Location {
46            file: file!(),
47            line: line!(),
48        }
49    };
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn test_error_handler() {
58        let err_result: Result<usize, &str> = Err("test_error");
59        let err_handled = err_result.handle_err(location!());
60        assert_eq!(err_handled.unwrap_err().to_str(), "test_error");
61
62        let ok_result: Result<usize, &str> = Ok(2);
63        let ok_handled = ok_result.handle_err(location!());
64        assert_eq!(ok_handled.unwrap(), 2);
65    }
66}