1use log::error;
7pub trait LogError {
9 fn log_error(self) -> Self;
11}
12
13impl<T, E: std::error::Error> LogError for std::result::Result<T, E> {
14 fn log_error(self) -> Self {
16 if let Some(error) = self.as_ref().err() {
17 error!("{error}");
18 }
19 self
20 }
21}
22
23#[cfg(test)]
24mod testing {
25 use crate::LogError;
26 use simple_logger::SimpleLogger;
27 use std::panic::set_hook;
28 use std::thread::spawn;
29 use thiserror::Error;
30
31 #[derive(Error, Debug, PartialOrd, PartialEq)]
32 enum TestError {
33 #[error("Unwrap or Log")]
34 UnwrapOrLog,
35 #[error("Log if error")]
36 LogIfError,
37 #[error("Ok or Log")]
38 OkOrLogError,
39 }
40
41 type TestResult<T> = std::result::Result<T, TestError>;
42
43 #[test]
44 fn test_unwrap_or_log_ok() {
45 let _ = SimpleLogger::default().init();
46 let data = 42;
47 let process = spawn(move || {
48 let value = TestResult::Ok(data).log_error().unwrap();
49 value
50 });
51
52 let join_result = process.join().unwrap();
53 assert_eq!(join_result, data);
54 }
55
56 #[test]
57 fn test_unwrap_or_log_error() {
58 let _ = SimpleLogger::default().init();
59 set_hook(Box::new(|_| {}));
60 let process = spawn(move || {
61 let value: i32 = TestResult::Err(TestError::UnwrapOrLog).log_error().unwrap();
62 value
63 });
64
65 let join_result = process.join();
66 assert!(join_result.is_err())
67 }
68
69 #[test]
70 fn test_log_if_error_ok() {
71 let _ = SimpleLogger::default().init();
72 let data = 42;
73 let result = TestResult::Ok(data).log_error();
74 assert_eq!(result, Ok(data))
75 }
76
77 #[test]
78 fn test_log_if_error_error() {
79 let _ = SimpleLogger::default().init();
80 let result: TestResult<i32> = TestResult::Err(TestError::LogIfError).log_error();
81 assert_eq!(result, Err(TestError::LogIfError))
82 }
83
84 #[test]
85 fn ok_or_log_ok() {
86 let _ = SimpleLogger::default().init();
87 let data = 42;
88 let result = TestResult::Ok(data).log_error().ok();
89 assert_eq!(result, Some(data))
90 }
91
92 #[test]
93 fn ok_or_log_error() {
94 let _ = SimpleLogger::default().init();
95 let result: Option<i32> = TestResult::Err(TestError::OkOrLogError).log_error().ok();
96 assert_eq!(result, None)
97 }
98}