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-tungstenite026")] use tokio_tungstenite026::tungstenite as tungstenite026;
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 #[cfg(feature = "tokio-tungstenite021")]
28 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite021")))]
29 #[error("unexpected type of WebSocket message")]
31 MessageKind021(tungstenite021::Message),
32 #[cfg(feature = "tokio-tungstenite024")]
33 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite024")))]
34 #[error("unexpected type of WebSocket message")]
36 MessageKind024(tungstenite024::Message),
37 #[cfg(feature = "tokio-tungstenite026")]
38 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite026")))]
39 #[error("unexpected type of WebSocket message")]
41 MessageKind026(tungstenite026::Message),
42 #[error("attempted to read an empty type")]
44 ReadNever,
45 #[error("{0:?}")] TryReserve(fallible_collections::TryReserveError),
47 #[error("unknown enum variant: {0}")]
48 UnknownVariant8(u8),
49 #[error("unknown enum variant: {0}")]
50 UnknownVariant16(u16),
51 #[error("unknown enum variant: {0}")]
52 UnknownVariant32(u32),
53 #[error("unknown enum variant: {0}")]
54 UnknownVariant64(u64),
55 #[error("unknown enum variant: {0}")]
56 UnknownVariant128(u128),
57 #[cfg(any(any(feature = "tokio-tungstenite021", feature = "tokio-tungstenite024")))]
58 #[cfg_attr(docsrs, doc(cfg(any(any(feature = "tokio-tungstenite021", feature = "tokio-tungstenite024")))))]
59 #[error("unexpected text message received from WebSocket: {0}")]
60 WebSocketTextMessage024(String),
61 #[cfg(any(feature = "tokio-tungstenite026"))]
62 #[cfg_attr(docsrs, doc(cfg(any(feature = "tokio-tungstenite026"))))]
63 #[error("unexpected text message received from WebSocket: {0}")]
64 WebSocketTextMessage026(tungstenite026::Utf8Bytes),
65 #[error(transparent)] Io(#[from] io::Error),
66 #[cfg(any(any(feature = "tokio-tungstenite021", feature = "tokio-tungstenite024", feature = "tokio-tungstenite026")))]
67 #[cfg_attr(docsrs, doc(cfg(any(any(feature = "tokio-tungstenite021", feature = "tokio-tungstenite024", feature = "tokio-tungstenite026")))))]
68 #[error(transparent)] ParseInt(#[from] std::num::ParseIntError),
69 #[cfg(any(feature = "tokio-tungstenite021"))]
70 #[cfg_attr(docsrs, doc(cfg(any(feature = "tokio-tungstenite021"))))]
71 #[error(transparent)] Tungstenite021(#[from] tungstenite021::Error),
72 #[cfg(any(feature = "tokio-tungstenite024"))]
73 #[cfg_attr(docsrs, doc(cfg(any(feature = "tokio-tungstenite024"))))]
74 #[error(transparent)] Tungstenite024(#[from] tungstenite024::Error),
75 #[cfg(any(feature = "tokio-tungstenite026"))]
76 #[cfg_attr(docsrs, doc(cfg(any(feature = "tokio-tungstenite026"))))]
77 #[error(transparent)] Tungstenite026(#[from] tungstenite026::Error),
78 #[error(transparent)] Utf8(#[from] std::string::FromUtf8Error),
79}
80
81impl From<Infallible> for ReadErrorKind {
82 fn from(never: Infallible) -> Self {
83 match never {}
84 }
85}
86
87impl From<String> for ReadErrorKind {
88 fn from(s: String) -> Self {
89 Self::Custom(s)
90 }
91}
92
93impl<'a> From<&'a str> for ReadErrorKind {
94 fn from(s: &str) -> Self {
95 Self::Custom(s.to_owned())
96 }
97}
98
99impl<'a> From<Cow<'a, str>> for ReadErrorKind {
100 fn from(s: Cow<'a, str>) -> Self {
101 Self::Custom(s.into_owned())
102 }
103}
104
105impl From<fallible_collections::TryReserveError> for ReadErrorKind {
106 fn from(e: fallible_collections::TryReserveError) -> Self {
107 Self::TryReserve(e)
108 }
109}
110
111impl From<ReadErrorKind> for io::Error {
112 fn from(e: ReadErrorKind) -> Self {
113 match e {
114 ReadErrorKind::BufSize(e) => io::Error::new(io::ErrorKind::InvalidData, e),
115 ReadErrorKind::Io(e) => e,
116 #[cfg(feature = "tokio-tungstenite021")] ReadErrorKind::Tungstenite021(e) => io::Error::new(io::ErrorKind::Other, e),
117 #[cfg(feature = "tokio-tungstenite024")] ReadErrorKind::Tungstenite024(e) => io::Error::new(io::ErrorKind::Other, e),
118 #[cfg(feature = "tokio-tungstenite026")] ReadErrorKind::Tungstenite026(e) => io::Error::new(io::ErrorKind::Other, e),
119 ReadErrorKind::Utf8(e) => io::Error::new(io::ErrorKind::InvalidData, e),
120 ReadErrorKind::EndOfStream => io::Error::new(io::ErrorKind::UnexpectedEof, e),
121 #[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),
122 #[cfg(feature = "tokio-tungstenite026")] ReadErrorKind::WebSocketTextMessage026(ref msg) => io::Error::new(if msg.is_empty() { io::ErrorKind::UnexpectedEof } else { io::ErrorKind::InvalidData }, e),
123 ReadErrorKind::FloatNotFinite |
124 ReadErrorKind::UnknownVariant8(_) |
125 ReadErrorKind::UnknownVariant16(_) |
126 ReadErrorKind::UnknownVariant32(_) |
127 ReadErrorKind::UnknownVariant64(_) |
128 ReadErrorKind::UnknownVariant128(_) => io::Error::new(io::ErrorKind::InvalidData, e),
129 #[cfg(feature = "tokio-tungstenite021")] ReadErrorKind::MessageKind021(_) => io::Error::new(io::ErrorKind::InvalidData, e),
130 #[cfg(feature = "tokio-tungstenite024")] ReadErrorKind::MessageKind024(_) => io::Error::new(io::ErrorKind::InvalidData, e),
131 #[cfg(feature = "tokio-tungstenite026")] ReadErrorKind::MessageKind026(_) => io::Error::new(io::ErrorKind::InvalidData, e),
132 #[cfg(any(feature = "tokio-tungstenite021", feature = "tokio-tungstenite024", feature = "tokio-tungstenite026"))] ReadErrorKind::ParseInt(_) => io::Error::new(io::ErrorKind::InvalidData, e),
133 ReadErrorKind::ReadNever => io::Error::new(io::ErrorKind::InvalidInput, e),
134 ReadErrorKind::TryReserve(_) => io::Error::new(io::ErrorKind::OutOfMemory, e),
135 ReadErrorKind::Custom(_) => io::Error::new(io::ErrorKind::Other, e),
136 }
137 }
138}
139
140impl From<ReadError> for io::Error {
141 fn from(ReadError { kind, .. }: ReadError) -> Self {
142 kind.into()
143 }
144}
145
146#[derive(Debug, thiserror::Error)]
148#[error("{kind}")]
149pub struct ReadError {
150 pub context: ErrorContext,
152 pub kind: ReadErrorKind,
154}
155
156#[derive(Debug, thiserror::Error)]
158#[allow(missing_docs)]
159pub enum WriteErrorKind {
160 #[error("tried to send a buffer with more than u64::MAX elements: {0}")]
162 BufSize(#[from] std::num::TryFromIntError),
163 #[error("{0}")]
165 Custom(String),
166 #[error(transparent)] Io(#[from] io::Error),
167 #[cfg(feature = "tokio-tungstenite021")]
168 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite021")))]
169 #[error(transparent)] Tungstenite021(#[from] tungstenite021::Error),
170 #[cfg(feature = "tokio-tungstenite024")]
171 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite024")))]
172 #[error(transparent)] Tungstenite024(#[from] tungstenite024::Error),
173 #[cfg(feature = "tokio-tungstenite026")]
174 #[cfg_attr(docsrs, doc(cfg(feature = "tokio-tungstenite026")))]
175 #[error(transparent)] Tungstenite026(#[from] tungstenite026::Error),
176}
177
178impl From<Infallible> for WriteErrorKind {
179 fn from(never: Infallible) -> Self {
180 match never {}
181 }
182}
183
184impl From<String> for WriteErrorKind {
185 fn from(s: String) -> Self {
186 Self::Custom(s)
187 }
188}
189
190impl<'a> From<&'a str> for WriteErrorKind {
191 fn from(s: &str) -> Self {
192 Self::Custom(s.to_owned())
193 }
194}
195
196impl<'a> From<Cow<'a, str>> for WriteErrorKind {
197 fn from(s: Cow<'a, str>) -> Self {
198 Self::Custom(s.into_owned())
199 }
200}
201
202impl From<WriteErrorKind> for io::Error {
203 fn from(e: WriteErrorKind) -> Self {
204 match e {
205 WriteErrorKind::BufSize(e) => io::Error::new(io::ErrorKind::InvalidData, e),
206 WriteErrorKind::Io(e) => e,
207 #[cfg(feature = "tokio-tungstenite021")] WriteErrorKind::Tungstenite021(e) => io::Error::new(io::ErrorKind::Other, e),
208 #[cfg(feature = "tokio-tungstenite024")] WriteErrorKind::Tungstenite024(e) => io::Error::new(io::ErrorKind::Other, e),
209 #[cfg(feature = "tokio-tungstenite026")] WriteErrorKind::Tungstenite026(e) => io::Error::new(io::ErrorKind::Other, e),
210 WriteErrorKind::Custom(_) => io::Error::new(io::ErrorKind::Other, e),
211 }
212 }
213}
214
215impl From<WriteError> for io::Error {
216 fn from(WriteError { kind, .. }: WriteError) -> Self {
217 kind.into()
218 }
219}
220
221#[derive(Debug, thiserror::Error)]
223#[error("{kind}")]
224pub struct WriteError {
225 pub context: ErrorContext,
227 pub kind: WriteErrorKind,
229}
230
231#[derive(Debug)]
233pub enum ErrorContext {
234 Custom(String),
236 BuiltIn {
238 for_type: &'static str,
242 },
243 WebSocket {
245 source: Box<Self>,
247 },
248 WebSocketSink,
250 WebSocketStream,
252 DefaultImpl,
254 Derived {
256 for_type: &'static str,
258 },
259 EnumDiscrim {
261 source: Box<Self>,
263 },
264 UnnamedField {
266 idx: usize,
268 source: Box<Self>,
270 },
271 NamedField {
273 name: &'static str,
275 source: Box<Self>,
277 },
278 FromStr,
280 AsString {
282 source: Box<Self>,
284 },
285 TryInto,
287 Via {
289 source: Box<Self>,
291 },
292 Bitflags {
294 source: Box<Self>,
296 },
297}