human_errors/
wrapper.rs

1use std::{borrow::Cow, fmt};
2
3/// Wraps an existing error with a basic message.
4///
5/// Generates a [std::error::Error] compatible error which wraps
6/// the provided inner error with the given message. Can be used
7/// as the internal error for a [crate::Error].
8///
9/// # Examples
10/// ```
11/// use human_errors;
12///
13/// human_errors::wrap(
14///   "ENOENT 2: No such file or directory",
15///   "We could not open the config file you provided."
16/// );
17/// ```
18pub 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}