1use std::{
2 borrow::Cow,
3 convert::Infallible,
4 io,
5};
6#[cfg(feature = "tokio-tungstenite021")] use tokio_tungstenite021::tungstenite as tungstenite021;
7#[cfg(feature = "tokio-tungstenite024")] use tokio_tungstenite024::tungstenite as tungstenite024;
8#[cfg(feature = "tokio-tungstenite027")] use tokio_tungstenite027::tungstenite as tungstenite027;
9
10#[derive(Debug, thiserror::Error)]
12#[allow(missing_docs)]
13pub enum ReadErrorKind {
14 #[error("received a buffer with more than usize::MAX elements: {0}")]
16 BufSize(#[from] std::num::TryFromIntError),
17 #[error("{0}")]
19 Custom(String),
20 #[error("reached end of stream")]
24 EndOfStream,
25 #[error("received an infinite or NaN number")]
26 FloatNotFinite,
27 #[error("received length ({len}) exceeds specified maximum length ({max_len})")]
28 MaxLen {
29 len: u64,
30 max_len: u64,
31 },
32 #[cfg(feature = "tokio-tungstenite021")]
33 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite021")))]
34 #[error("unexpected type of WebSocket message")]
36 MessageKind021(tungstenite021::Message),
37 #[cfg(feature = "tokio-tungstenite024")]
38 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite024")))]
39 #[error("unexpected type of WebSocket message")]
41 MessageKind024(tungstenite024::Message),
42 #[cfg(feature = "tokio-tungstenite027")]
43 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite027")))]
44 #[error("unexpected type of WebSocket message")]
46 MessageKind027(tungstenite027::Message),
47 #[error("attempted to read an empty type")]
49 ReadNever,
50 #[error("{0:?}")] TryReserve(fallible_collections::TryReserveError),
52 #[error("unknown enum variant: {0}")]
53 UnknownVariant8(u8),
54 #[error("unknown enum variant: {0}")]
55 UnknownVariant16(u16),
56 #[error("unknown enum variant: {0}")]
57 UnknownVariant32(u32),
58 #[error("unknown enum variant: {0}")]
59 UnknownVariant64(u64),
60 #[error("unknown enum variant: {0}")]
61 UnknownVariant128(u128),
62 #[cfg(any(any(feature = "tokio-tungstenite021", feature = "tokio-tungstenite024")))]
63 #[cfg_attr(docsrs, doc(cfg(any(any(feature = "tokio-tungstenite021", feature = "tokio-tungstenite024")))))]
64 #[error("unexpected text message received from WebSocket: {0}")]
65 WebSocketTextMessage024(String),
66 #[cfg(any(feature = "tokio-tungstenite027"))]
67 #[cfg_attr(docsrs, doc(cfg(any(feature = "tokio-tungstenite027"))))]
68 #[error("unexpected text message received from WebSocket: {0}")]
69 WebSocketTextMessage027(tungstenite027::Utf8Bytes),
70 #[error(transparent)] Io(#[from] io::Error),
71 #[cfg(any(any(feature = "tokio-tungstenite021", feature = "tokio-tungstenite024", feature = "tokio-tungstenite027")))]
72 #[cfg_attr(docsrs, doc(cfg(any(any(feature = "tokio-tungstenite021", feature = "tokio-tungstenite024", feature = "tokio-tungstenite027")))))]
73 #[error(transparent)] ParseInt(#[from] std::num::ParseIntError),
74 #[cfg(any(feature = "tokio-tungstenite021"))]
75 #[cfg_attr(docsrs, doc(cfg(any(feature = "tokio-tungstenite021"))))]
76 #[error(transparent)] Tungstenite021(#[from] tungstenite021::Error),
77 #[cfg(any(feature = "tokio-tungstenite024"))]
78 #[cfg_attr(docsrs, doc(cfg(any(feature = "tokio-tungstenite024"))))]
79 #[error(transparent)] Tungstenite024(#[from] tungstenite024::Error),
80 #[cfg(any(feature = "tokio-tungstenite027"))]
81 #[cfg_attr(docsrs, doc(cfg(any(feature = "tokio-tungstenite027"))))]
82 #[error(transparent)] Tungstenite027(#[from] tungstenite027::Error),
83 #[error(transparent)] Utf8(#[from] std::string::FromUtf8Error),
84}
85
86impl From<Infallible> for ReadErrorKind {
87 fn from(never: Infallible) -> Self {
88 match never {}
89 }
90}
91
92impl From<String> for ReadErrorKind {
93 fn from(s: String) -> Self {
94 Self::Custom(s)
95 }
96}
97
98impl<'a> From<&'a str> for ReadErrorKind {
99 fn from(s: &str) -> Self {
100 Self::Custom(s.to_owned())
101 }
102}
103
104impl<'a> From<Cow<'a, str>> for ReadErrorKind {
105 fn from(s: Cow<'a, str>) -> Self {
106 Self::Custom(s.into_owned())
107 }
108}
109
110impl From<fallible_collections::TryReserveError> for ReadErrorKind {
111 fn from(e: fallible_collections::TryReserveError) -> Self {
112 Self::TryReserve(e)
113 }
114}
115
116impl From<ReadErrorKind> for io::Error {
117 fn from(e: ReadErrorKind) -> Self {
118 match e {
119 ReadErrorKind::BufSize(e) => io::Error::new(io::ErrorKind::InvalidData, e),
120 ReadErrorKind::Io(e) => e,
121 #[cfg(feature = "tokio-tungstenite021")] ReadErrorKind::Tungstenite021(e) => io::Error::new(io::ErrorKind::Other, e),
122 #[cfg(feature = "tokio-tungstenite024")] ReadErrorKind::Tungstenite024(e) => io::Error::new(io::ErrorKind::Other, e),
123 #[cfg(feature = "tokio-tungstenite027")] ReadErrorKind::Tungstenite027(e) => io::Error::new(io::ErrorKind::Other, e),
124 ReadErrorKind::Utf8(e) => io::Error::new(io::ErrorKind::InvalidData, e),
125 ReadErrorKind::EndOfStream => io::Error::new(io::ErrorKind::UnexpectedEof, e),
126 #[cfg(any(feature = "tokio-tungstenite021", feature = "tokio-tungstenite024"))] ReadErrorKind::WebSocketTextMessage024(ref msg) => io::Error::new(if msg.is_empty() { io::ErrorKind::UnexpectedEof } else { io::ErrorKind::InvalidData }, e),
127 #[cfg(feature = "tokio-tungstenite027")] ReadErrorKind::WebSocketTextMessage027(ref msg) => io::Error::new(if msg.is_empty() { io::ErrorKind::UnexpectedEof } else { io::ErrorKind::InvalidData }, e),
128 ReadErrorKind::FloatNotFinite |
129 ReadErrorKind::MaxLen { .. } |
130 ReadErrorKind::UnknownVariant8(_) |
131 ReadErrorKind::UnknownVariant16(_) |
132 ReadErrorKind::UnknownVariant32(_) |
133 ReadErrorKind::UnknownVariant64(_) |
134 ReadErrorKind::UnknownVariant128(_) => io::Error::new(io::ErrorKind::InvalidData, e),
135 #[cfg(feature = "tokio-tungstenite021")] ReadErrorKind::MessageKind021(_) => io::Error::new(io::ErrorKind::InvalidData, e),
136 #[cfg(feature = "tokio-tungstenite024")] ReadErrorKind::MessageKind024(_) => io::Error::new(io::ErrorKind::InvalidData, e),
137 #[cfg(feature = "tokio-tungstenite027")] ReadErrorKind::MessageKind027(_) => io::Error::new(io::ErrorKind::InvalidData, e),
138 #[cfg(any(feature = "tokio-tungstenite021", feature = "tokio-tungstenite024", feature = "tokio-tungstenite027"))] ReadErrorKind::ParseInt(_) => io::Error::new(io::ErrorKind::InvalidData, e),
139 ReadErrorKind::ReadNever => io::Error::new(io::ErrorKind::InvalidInput, e),
140 ReadErrorKind::TryReserve(_) => io::Error::new(io::ErrorKind::OutOfMemory, e),
141 ReadErrorKind::Custom(_) => io::Error::new(io::ErrorKind::Other, e),
142 }
143 }
144}
145
146impl From<ReadError> for io::Error {
147 fn from(ReadError { kind, .. }: ReadError) -> Self {
148 kind.into()
149 }
150}
151
152#[derive(Debug, thiserror::Error)]
154#[error("{kind}")]
155pub struct ReadError {
156 pub context: ErrorContext,
158 pub kind: ReadErrorKind,
160}
161
162#[derive(Debug, thiserror::Error)]
164#[allow(missing_docs)]
165pub enum WriteErrorKind {
166 #[error("tried to send a buffer with more than u64::MAX elements: {0}")]
168 BufSize(#[from] std::num::TryFromIntError),
169 #[error("{0}")]
171 Custom(String),
172 #[error(transparent)] Io(#[from] io::Error),
173 #[error("attempted to write length {len} exceeding specified maximum length ({max_len})")]
174 MaxLen {
175 len: u64,
176 max_len: u64,
177 },
178 #[cfg(feature = "tokio-tungstenite021")]
179 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite021")))]
180 #[error(transparent)] Tungstenite021(#[from] tungstenite021::Error),
181 #[cfg(feature = "tokio-tungstenite024")]
182 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite024")))]
183 #[error(transparent)] Tungstenite024(#[from] tungstenite024::Error),
184 #[cfg(feature = "tokio-tungstenite027")]
185 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite027")))]
186 #[error(transparent)] Tungstenite027(#[from] tungstenite027::Error),
187}
188
189impl From<Infallible> for WriteErrorKind {
190 fn from(never: Infallible) -> Self {
191 match never {}
192 }
193}
194
195impl From<String> for WriteErrorKind {
196 fn from(s: String) -> Self {
197 Self::Custom(s)
198 }
199}
200
201impl<'a> From<&'a str> for WriteErrorKind {
202 fn from(s: &str) -> Self {
203 Self::Custom(s.to_owned())
204 }
205}
206
207impl<'a> From<Cow<'a, str>> for WriteErrorKind {
208 fn from(s: Cow<'a, str>) -> Self {
209 Self::Custom(s.into_owned())
210 }
211}
212
213impl From<WriteErrorKind> for io::Error {
214 fn from(e: WriteErrorKind) -> Self {
215 match e {
216 WriteErrorKind::BufSize(e) => io::Error::new(io::ErrorKind::InvalidData, e),
217 WriteErrorKind::Io(e) => e,
218 WriteErrorKind::MaxLen { .. } => io::Error::new(io::ErrorKind::InvalidData, e),
219 #[cfg(feature = "tokio-tungstenite021")] WriteErrorKind::Tungstenite021(e) => io::Error::new(io::ErrorKind::Other, e),
220 #[cfg(feature = "tokio-tungstenite024")] WriteErrorKind::Tungstenite024(e) => io::Error::new(io::ErrorKind::Other, e),
221 #[cfg(feature = "tokio-tungstenite027")] WriteErrorKind::Tungstenite027(e) => io::Error::new(io::ErrorKind::Other, e),
222 WriteErrorKind::Custom(_) => io::Error::new(io::ErrorKind::Other, e),
223 }
224 }
225}
226
227impl From<WriteError> for io::Error {
228 fn from(WriteError { kind, .. }: WriteError) -> Self {
229 kind.into()
230 }
231}
232
233#[derive(Debug, thiserror::Error)]
235#[error("{kind}")]
236pub struct WriteError {
237 pub context: ErrorContext,
239 pub kind: WriteErrorKind,
241}
242
243#[derive(Debug)]
245pub enum ErrorContext {
246 Custom(String),
248 BuiltIn {
250 for_type: &'static str,
254 },
255 WebSocket {
257 source: Box<Self>,
259 },
260 WebSocketSink,
262 WebSocketStream,
264 DefaultImpl,
266 Derived {
268 for_type: &'static str,
270 },
271 EnumDiscrim {
273 source: Box<Self>,
275 },
276 UnnamedField {
278 idx: usize,
280 source: Box<Self>,
282 },
283 NamedField {
285 name: &'static str,
287 source: Box<Self>,
289 },
290 FromStr,
292 AsString {
294 source: Box<Self>,
296 },
297 TryInto,
299 Via {
301 source: Box<Self>,
303 },
304 Bitflags {
306 source: Box<Self>,
308 },
309}