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