little_stomper/error/
mod.rs1use std::convert::{From, Infallible};
2use std::error::Error;
3use std::fmt::{self, Display, Formatter};
4
5use sender_sink::wrappers::SinkError;
6use stomp_parser::error::StompParseError;
7
8#[derive(Debug, PartialEq, Eq, Clone)]
9pub struct StomperError {
10 pub message: String,
11}
12
13impl StomperError {
14 pub fn new(message: &str) -> StomperError {
15 StomperError {
16 message: message.to_owned(),
17 }
18 }
19}
20
21impl From<StompParseError> for StomperError {
22 fn from(err: StompParseError) -> Self {
23 StomperError {
24 message: err.message().to_owned(),
25 }
26 }
27}
28
29impl From<Infallible> for StomperError {
30 fn from(_: Infallible) -> Self {
31 StomperError {
32 message: "Should have been Infallible!".to_owned(),
33 }
34 }
35}
36
37impl From<SinkError> for StomperError {
38 fn from(err: SinkError) -> Self {
39 StomperError {
40 message: format!("Error sending to Sink: {:?}", err),
41 }
42 }
43}
44
45impl Display for StomperError {
46 fn fmt(
47 &self,
48 formatter: &mut std::fmt::Formatter<'_>,
49 ) -> std::result::Result<(), std::fmt::Error> {
50 formatter.write_str(&self.message)
51 }
52}
53
54#[derive(Debug)]
55pub struct ErrorWrapper(Box<dyn Error + Send + Sync>);
56
57impl ErrorWrapper {
58 pub(crate) fn new<E: Into<Box<dyn Error + Send + Sync>>>(err: E) -> ErrorWrapper {
59 ErrorWrapper(err.into())
60 }
61}
62
63impl Display for ErrorWrapper {
64 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
65 write!(f, "{:?},", self.0)
66 }
67}
68
69impl<T> From<T> for ErrorWrapper
70where
71 T: Error + Send + Sync + 'static,
72{
73 fn from(err: T) -> Self {
74 ErrorWrapper::new(err)
75 }
76}
77
78#[derive(Debug)]
79pub struct UnknownCommandError {
80 text: &'static str,
81}
82
83impl Display for UnknownCommandError {
84 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
85 write!(f, "Unknown command {:?}", self.text)
86 }
87}
88
89impl Error for UnknownCommandError {}
90
91#[cfg(test)]
92mod test {
93 use sender_sink::wrappers::SinkError;
94 use stomp_parser::error::StompParseError;
95
96 use crate::error::{ErrorWrapper, StomperError};
97 use std::convert::Infallible;
98 use std::error::Error;
99 use std::fmt::{Display, Formatter};
100 #[derive(Debug)]
101 struct ErrorForTest(u32);
102
103 impl Error for ErrorForTest {}
104
105 impl Display for ErrorForTest {
106 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
107 write!(f, "ErrorForTest({})", self.0)
108 }
109 }
110
111 #[test]
112 fn wraps_error() {
113 let error = ErrorForTest(42);
114
115 let wrapped_error = ErrorWrapper::new(error);
116
117 assert_eq!(42, wrapped_error.0.downcast::<ErrorForTest>().unwrap().0);
118 }
119
120 #[test]
121 fn from_stomp_parse_error() {
122 let src = StompParseError::new("freaky");
123 let error: StomperError = src.into();
124
125 assert_eq!("freaky", error.message);
126 }
127
128 #[test]
129 fn from_sink_error() {
130 let src = SinkError::ChannelClosed;
131 let error: StomperError = src.into();
132
133 assert!(error.message.contains("Closed"));
134 }
135
136 fn never_error() -> Result<(), Infallible> {
137 Ok(())
138 }
139
140 #[test]
141 fn from_infallible() {
142 let src = never_error();
143 let target = src.map_err(StomperError::from);
144
145 assert!(target.is_ok());
147 }
148
149 #[test]
150 fn error_display() {
151 let src = StomperError::new("Hello, world!");
152
153 assert_eq!("Hello, world!", src.to_string());
155 }
156}