1use std::borrow::Cow;
2
3use anyhow::{Error, Result};
4
5pub trait ErrorFormatter: Send + Sync {
9 fn format_error(&self, error: &Error) -> Cow<'_, str>;
11}
12
13pub trait ErrorReporter: Send + Sync {
15 fn capture(&self, error: &Error) -> Result<()>;
17
18 fn capture_message(&self, message: impl Into<Cow<'static, str>>) -> Result<()> {
20 let message: Cow<'static, str> = message.into();
21 self.capture(&Error::msg(message))
22 }
23}
24
25#[derive(Debug, Default, Clone, Copy)]
28pub struct NoopErrorReporter;
29
30impl ErrorReporter for NoopErrorReporter {
31 fn capture(&self, _error: &Error) -> Result<()> {
32 Ok(())
33 }
34}
35
36#[derive(Debug, Default, Clone, Copy)]
38pub struct DisplayErrorFormatter;
39
40impl ErrorFormatter for DisplayErrorFormatter {
41 fn format_error(&self, error: &Error) -> Cow<'_, str> {
42 Cow::Owned(format!("{error}"))
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn formatter_uses_display() {
52 let formatter = DisplayErrorFormatter;
53 let error = Error::msg("test error");
54 assert_eq!(formatter.format_error(&error), "test error");
55 }
56
57 #[test]
58 fn noop_reporter_drops_errors() {
59 let reporter = NoopErrorReporter;
60 let error = Error::msg("test");
61 assert!(reporter.capture(&error).is_ok());
62 assert!(reporter.capture_message("message").is_ok());
63 }
64}