1#[cfg(feature = "std")]
11use thiserror::Error;
12
13#[cfg(feature = "std")]
17#[derive(Error, Debug)]
18pub enum DDPError {
19 #[error("socket error")]
21 Disconnect(#[from] std::io::Error),
22
23 #[error("No valid socket addr found")]
25 NoValidSocketAddr,
26
27 #[error("parse error")]
29 ParseError(#[from] serde_json::Error),
30
31 #[error("invalid sender, did you forget to connect() ( data from {from:?} - {data:?})")]
33 UnknownClient {
34 from: std::net::SocketAddr,
36 data: Vec<u8>,
38 },
39
40 #[error("Invalid packet")]
42 InvalidPacket,
43
44 #[error("There are no packets waiting to be read. This error should be handled explicitly")]
46 NothingToReceive,
47
48 #[error("Error receiving packet: {0}")]
50 CrossBeamError(#[from] crossbeam::channel::TryRecvError),
51}
52
53#[cfg(all(test, feature = "std"))]
54mod tests {
55 use super::*;
56 use std::net::{IpAddr, Ipv4Addr, SocketAddr};
57
58 #[test]
59 fn test_error_display_disconnect() {
60 let io_error = std::io::Error::new(std::io::ErrorKind::ConnectionReset, "connection reset");
61 let error = DDPError::Disconnect(io_error);
62 assert_eq!(error.to_string(), "socket error");
63 }
64
65 #[test]
66 fn test_error_display_no_valid_socket_addr() {
67 let error = DDPError::NoValidSocketAddr;
68 assert_eq!(error.to_string(), "No valid socket addr found");
69 }
70
71 #[test]
72 fn test_error_display_parse_error() {
73 let json_error = serde_json::from_str::<serde_json::Value>("{invalid json")
74 .expect_err("should fail to parse");
75 let error = DDPError::ParseError(json_error);
76 assert_eq!(error.to_string(), "parse error");
77 }
78
79 #[test]
80 fn test_error_display_unknown_client() {
81 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 8080);
82 let data = vec![0x01, 0x02, 0x03];
83 let error = DDPError::UnknownClient {
84 from: addr,
85 data: data.clone(),
86 };
87
88 let error_str = error.to_string();
89 assert!(error_str.contains("invalid sender"));
90 assert!(error_str.contains("192.168.1.1:8080"));
91 assert!(error_str.contains("[1, 2, 3]"));
92 }
93
94 #[test]
95 fn test_error_display_invalid_packet() {
96 let error = DDPError::InvalidPacket;
97 assert_eq!(error.to_string(), "Invalid packet");
98 }
99
100 #[test]
101 fn test_error_display_nothing_to_receive() {
102 let error = DDPError::NothingToReceive;
103 assert_eq!(
104 error.to_string(),
105 "There are no packets waiting to be read. This error should be handled explicitly"
106 );
107 }
108
109 #[test]
110 fn test_error_display_crossbeam_error() {
111 use crossbeam::channel::TryRecvError;
112
113 let error = DDPError::CrossBeamError(TryRecvError::Empty);
114 assert!(error.to_string().contains("Error receiving packet"));
115 }
116
117 #[test]
118 fn test_error_from_io_error() {
119 let io_error = std::io::Error::new(std::io::ErrorKind::BrokenPipe, "broken pipe");
120 let error: DDPError = io_error.into();
121
122 match error {
123 DDPError::Disconnect(_) => {},
124 _ => panic!("Expected Disconnect variant"),
125 }
126 }
127
128 #[test]
129 fn test_error_from_json_error() {
130 let json_error = serde_json::from_str::<serde_json::Value>("{bad}")
131 .expect_err("should fail");
132 let error: DDPError = json_error.into();
133
134 match error {
135 DDPError::ParseError(_) => {},
136 _ => panic!("Expected ParseError variant"),
137 }
138 }
139
140 #[test]
141 fn test_error_from_crossbeam_error() {
142 use crossbeam::channel::TryRecvError;
143
144 let crossbeam_error = TryRecvError::Disconnected;
145 let error: DDPError = crossbeam_error.into();
146
147 match error {
148 DDPError::CrossBeamError(_) => {},
149 _ => panic!("Expected CrossBeamError variant"),
150 }
151 }
152
153 #[test]
154 fn test_error_debug_format() {
155 let error = DDPError::InvalidPacket;
156 let debug_str = format!("{:?}", error);
157 assert_eq!(debug_str, "InvalidPacket");
158 }
159
160 #[test]
161 fn test_unknown_client_error_fields() {
162 let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 4048);
163 let data = vec![0xDE, 0xAD, 0xBE, 0xEF];
164
165 let error = DDPError::UnknownClient {
166 from: addr,
167 data: data.clone(),
168 };
169
170 match error {
171 DDPError::UnknownClient { from, data: d } => {
172 assert_eq!(from, addr);
173 assert_eq!(d, data);
174 }
175 _ => panic!("Expected UnknownClient variant"),
176 }
177 }
178
179 #[test]
180 fn test_error_is_send_sync() {
181 fn assert_send_sync<T: Send + Sync>() {}
182 assert_send_sync::<DDPError>();
183 }
184}