1use std::fmt;
10
11#[derive(Debug)]
13pub enum StreamError<D> {
14 Database(D),
16 Deserialize(String)
18}
19
20impl<D> StreamError<D> {
21 pub const fn is_database(&self) -> bool {
23 matches!(self, Self::Database(_))
24 }
25
26 pub const fn is_deserialize(&self) -> bool {
28 matches!(self, Self::Deserialize(_))
29 }
30}
31
32impl<D: fmt::Display> fmt::Display for StreamError<D> {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 match self {
35 Self::Database(e) => write!(f, "database error: {e}"),
36 Self::Deserialize(e) => write!(f, "deserialize error: {e}")
37 }
38 }
39}
40
41impl<D: std::error::Error + 'static> std::error::Error for StreamError<D> {
42 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
43 match self {
44 Self::Database(e) => Some(e),
45 Self::Deserialize(_) => None
46 }
47 }
48}
49
50#[cfg(test)]
51#[allow(clippy::uninlined_format_args)]
52mod tests {
53 use super::*;
54
55 #[derive(Debug)]
56 struct TestError(&'static str);
57
58 impl fmt::Display for TestError {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 write!(f, "{}", self.0)
61 }
62 }
63
64 impl std::error::Error for TestError {}
65
66 #[test]
67 fn stream_error_is_database() {
68 let err: StreamError<TestError> = StreamError::Database(TestError("db"));
69 assert!(err.is_database());
70 assert!(!err.is_deserialize());
71 }
72
73 #[test]
74 fn stream_error_is_deserialize() {
75 let err: StreamError<TestError> = StreamError::Deserialize("json".into());
76 assert!(err.is_deserialize());
77 assert!(!err.is_database());
78 }
79
80 #[test]
81 fn stream_error_display() {
82 let db: StreamError<TestError> = StreamError::Database(TestError("conn"));
83 assert_eq!(format!("{}", db), "database error: conn");
84
85 let de: StreamError<TestError> = StreamError::Deserialize("invalid".into());
86 assert_eq!(format!("{}", de), "deserialize error: invalid");
87 }
88
89 #[test]
90 fn stream_error_source() {
91 use std::error::Error;
92
93 let db: StreamError<TestError> = StreamError::Database(TestError("source"));
94 assert!(db.source().is_some());
95
96 let de: StreamError<TestError> = StreamError::Deserialize("no source".into());
97 assert!(de.source().is_none());
98 }
99}