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)]
51mod tests {
52 use super::*;
53
54 #[derive(Debug)]
55 struct TestError(&'static str);
56
57 impl fmt::Display for TestError {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 write!(f, "{}", self.0)
60 }
61 }
62
63 impl std::error::Error for TestError {}
64
65 #[test]
66 fn stream_error_is_database() {
67 let err: StreamError<TestError> = StreamError::Database(TestError("db"));
68 assert!(err.is_database());
69 assert!(!err.is_deserialize());
70 }
71
72 #[test]
73 fn stream_error_is_deserialize() {
74 let err: StreamError<TestError> = StreamError::Deserialize("json".into());
75 assert!(err.is_deserialize());
76 assert!(!err.is_database());
77 }
78
79 #[test]
80 fn stream_error_display() {
81 let db: StreamError<TestError> = StreamError::Database(TestError("conn"));
82 assert_eq!(format!("{}", db), "database error: conn");
83
84 let de: StreamError<TestError> = StreamError::Deserialize("invalid".into());
85 assert_eq!(format!("{}", de), "deserialize error: invalid");
86 }
87
88 #[test]
89 fn stream_error_source() {
90 use std::error::Error;
91
92 let db: StreamError<TestError> = StreamError::Database(TestError("source"));
93 assert!(db.source().is_some());
94
95 let de: StreamError<TestError> = StreamError::Deserialize("no source".into());
96 assert!(de.source().is_none());
97 }
98}