Skip to main content

slog_cloud/
error.rs

1use std::{
2    borrow::Cow,
3    fmt::{self, Display, Formatter},
4};
5
6/// Error.
7#[derive(Debug)]
8pub struct Error {
9    msg: Cow<'static, str>,
10    cause: Option<Box<dyn std::error::Error + Send + Sync>>,
11}
12
13impl Error {
14    /// Create a new error with a given message.
15    pub fn from_msg<T>(msg: T) -> Self
16    where
17        T: Into<String>,
18    {
19        Self {
20            msg: Cow::Owned(msg.into()),
21            cause: None,
22        }
23    }
24
25    /// Create a new error with a given message.
26    #[inline]
27    pub const fn from_static_msg(msg: &'static str) -> Self {
28        Self {
29            msg: Cow::Borrowed(msg),
30            cause: None,
31        }
32    }
33
34    /// Create a new error with a given message and cause.
35    pub fn from_msg_and_cause<T, E>(msg: T, err: E) -> Self
36    where
37        T: Into<String>,
38        E: Into<Box<dyn std::error::Error + Send + Sync>>,
39    {
40        Self {
41            msg: Cow::Owned(msg.into()),
42            cause: Some(err.into()),
43        }
44    }
45
46    /// Create a new error with a given message and cause.
47    pub fn from_static_msg_and_cause<E>(msg: &'static str, err: E) -> Self
48    where
49        E: Into<Box<dyn std::error::Error + Send + Sync>>,
50    {
51        Self {
52            msg: Cow::Borrowed(msg),
53            cause: Some(err.into()),
54        }
55    }
56
57    /// Create a new error from a given cause.
58    pub fn from_cause<E>(err: E) -> Self
59    where
60        E: Into<Box<dyn std::error::Error + Send + Sync>>,
61    {
62        Self {
63            msg: Cow::Borrowed(""),
64            cause: Some(err.into()),
65        }
66    }
67}
68
69impl std::error::Error for Error {
70    #[inline]
71    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
72        self.cause.as_ref().map(|err| &**err as _)
73    }
74}
75
76impl Display for Error {
77    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
78        if let Some(cause) = self.cause.as_ref() {
79            if self.msg.is_empty() {
80                Display::fmt(cause, f)
81            } else {
82                write!(f, "{}: {}", self.msg, cause)
83            }
84        } else if self.msg.is_empty() {
85            f.write_str("unknown error")
86        } else {
87            f.write_str(&self.msg)
88        }
89    }
90}