ttpkit_utils/
error.rs

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