1use std::{borrow::Cow, fmt};
2
3pub fn wrap<
19 S: Into<Cow<'static, str>>,
20 E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
21>(
22 inner: E,
23 message: S,
24) -> impl std::error::Error {
25 let message = message.into();
26 ErrorWithMessage {
27 message,
28 inner: Some(inner.into()),
29 }
30}
31
32#[derive(Debug)]
33struct ErrorWithMessage {
34 message: Cow<'static, str>,
35 inner: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
36}
37
38impl std::error::Error for ErrorWithMessage {
39 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
40 match &self.inner {
41 Some(inner) => Some(&**inner),
42 None => None,
43 }
44 }
45}
46
47impl fmt::Display for ErrorWithMessage {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 write!(f, "{}", self.message)
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56 use crate::*;
57
58 #[test]
59 fn test_message_internal() {
60 assert_eq!(
61 user(
62 wrap("You got rate limited", "Something bad happened."),
63 &["Avoid bad things happening in future"],
64 )
65 .message(),
66 "Something bad happened. (User error)\n\nThis was caused by:\n - You got rate limited\n\nTo try and fix this, you can:\n - Avoid bad things happening in future"
67 );
68
69 assert_eq!(
70 system(
71 wrap("You got rate limited", "Something bad happened."),
72 &["Avoid bad things happening in future"],
73 )
74 .message(),
75 "Something bad happened. (System failure)\n\nThis was caused by:\n - You got rate limited\n\nTo try and fix this, you can:\n - Avoid bad things happening in future"
76 );
77 }
78}