wreq-rb 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. checksums.yaml +7 -0
  2. data/Cargo.lock +2688 -0
  3. data/Cargo.toml +6 -0
  4. data/README.md +179 -0
  5. data/ext/wreq_rb/Cargo.toml +39 -0
  6. data/ext/wreq_rb/extconf.rb +22 -0
  7. data/ext/wreq_rb/src/client.rs +565 -0
  8. data/ext/wreq_rb/src/error.rs +25 -0
  9. data/ext/wreq_rb/src/lib.rs +20 -0
  10. data/ext/wreq_rb/src/response.rs +132 -0
  11. data/lib/wreq-rb/version.rb +5 -0
  12. data/lib/wreq-rb.rb +17 -0
  13. data/patches/0001-add-transfer-size-tracking.patch +292 -0
  14. data/vendor/wreq/Cargo.toml +306 -0
  15. data/vendor/wreq/LICENSE +202 -0
  16. data/vendor/wreq/README.md +122 -0
  17. data/vendor/wreq/examples/cert_store.rs +77 -0
  18. data/vendor/wreq/examples/connect_via_lower_priority_tokio_runtime.rs +258 -0
  19. data/vendor/wreq/examples/emulation.rs +118 -0
  20. data/vendor/wreq/examples/form.rs +14 -0
  21. data/vendor/wreq/examples/http1_websocket.rs +37 -0
  22. data/vendor/wreq/examples/http2_websocket.rs +45 -0
  23. data/vendor/wreq/examples/json_dynamic.rs +41 -0
  24. data/vendor/wreq/examples/json_typed.rs +47 -0
  25. data/vendor/wreq/examples/keylog.rs +16 -0
  26. data/vendor/wreq/examples/request_with_emulation.rs +115 -0
  27. data/vendor/wreq/examples/request_with_interface.rs +37 -0
  28. data/vendor/wreq/examples/request_with_local_address.rs +16 -0
  29. data/vendor/wreq/examples/request_with_proxy.rs +13 -0
  30. data/vendor/wreq/examples/request_with_redirect.rs +22 -0
  31. data/vendor/wreq/examples/request_with_version.rs +15 -0
  32. data/vendor/wreq/examples/tor_socks.rs +24 -0
  33. data/vendor/wreq/examples/unix_socket.rs +33 -0
  34. data/vendor/wreq/src/client/body.rs +304 -0
  35. data/vendor/wreq/src/client/conn/conn.rs +231 -0
  36. data/vendor/wreq/src/client/conn/connector.rs +549 -0
  37. data/vendor/wreq/src/client/conn/http.rs +1023 -0
  38. data/vendor/wreq/src/client/conn/proxy/socks.rs +233 -0
  39. data/vendor/wreq/src/client/conn/proxy/tunnel.rs +260 -0
  40. data/vendor/wreq/src/client/conn/proxy.rs +39 -0
  41. data/vendor/wreq/src/client/conn/tls_info.rs +98 -0
  42. data/vendor/wreq/src/client/conn/uds.rs +44 -0
  43. data/vendor/wreq/src/client/conn/verbose.rs +149 -0
  44. data/vendor/wreq/src/client/conn.rs +323 -0
  45. data/vendor/wreq/src/client/core/body/incoming.rs +485 -0
  46. data/vendor/wreq/src/client/core/body/length.rs +118 -0
  47. data/vendor/wreq/src/client/core/body.rs +34 -0
  48. data/vendor/wreq/src/client/core/common/buf.rs +149 -0
  49. data/vendor/wreq/src/client/core/common/rewind.rs +141 -0
  50. data/vendor/wreq/src/client/core/common/watch.rs +76 -0
  51. data/vendor/wreq/src/client/core/common.rs +3 -0
  52. data/vendor/wreq/src/client/core/conn/http1.rs +342 -0
  53. data/vendor/wreq/src/client/core/conn/http2.rs +307 -0
  54. data/vendor/wreq/src/client/core/conn.rs +11 -0
  55. data/vendor/wreq/src/client/core/dispatch.rs +299 -0
  56. data/vendor/wreq/src/client/core/error.rs +435 -0
  57. data/vendor/wreq/src/client/core/ext.rs +201 -0
  58. data/vendor/wreq/src/client/core/http1.rs +178 -0
  59. data/vendor/wreq/src/client/core/http2.rs +483 -0
  60. data/vendor/wreq/src/client/core/proto/h1/conn.rs +988 -0
  61. data/vendor/wreq/src/client/core/proto/h1/decode.rs +1170 -0
  62. data/vendor/wreq/src/client/core/proto/h1/dispatch.rs +684 -0
  63. data/vendor/wreq/src/client/core/proto/h1/encode.rs +580 -0
  64. data/vendor/wreq/src/client/core/proto/h1/io.rs +879 -0
  65. data/vendor/wreq/src/client/core/proto/h1/role.rs +694 -0
  66. data/vendor/wreq/src/client/core/proto/h1.rs +104 -0
  67. data/vendor/wreq/src/client/core/proto/h2/client.rs +650 -0
  68. data/vendor/wreq/src/client/core/proto/h2/ping.rs +539 -0
  69. data/vendor/wreq/src/client/core/proto/h2.rs +379 -0
  70. data/vendor/wreq/src/client/core/proto/headers.rs +138 -0
  71. data/vendor/wreq/src/client/core/proto.rs +58 -0
  72. data/vendor/wreq/src/client/core/rt/bounds.rs +57 -0
  73. data/vendor/wreq/src/client/core/rt/timer.rs +150 -0
  74. data/vendor/wreq/src/client/core/rt/tokio.rs +99 -0
  75. data/vendor/wreq/src/client/core/rt.rs +25 -0
  76. data/vendor/wreq/src/client/core/upgrade.rs +267 -0
  77. data/vendor/wreq/src/client/core.rs +16 -0
  78. data/vendor/wreq/src/client/emulation.rs +161 -0
  79. data/vendor/wreq/src/client/http/client/error.rs +142 -0
  80. data/vendor/wreq/src/client/http/client/exec.rs +29 -0
  81. data/vendor/wreq/src/client/http/client/extra.rs +77 -0
  82. data/vendor/wreq/src/client/http/client/lazy.rs +79 -0
  83. data/vendor/wreq/src/client/http/client/pool.rs +1105 -0
  84. data/vendor/wreq/src/client/http/client/util.rs +104 -0
  85. data/vendor/wreq/src/client/http/client.rs +1003 -0
  86. data/vendor/wreq/src/client/http/future.rs +99 -0
  87. data/vendor/wreq/src/client/http.rs +1629 -0
  88. data/vendor/wreq/src/client/layer/config/options.rs +156 -0
  89. data/vendor/wreq/src/client/layer/config.rs +116 -0
  90. data/vendor/wreq/src/client/layer/cookie.rs +161 -0
  91. data/vendor/wreq/src/client/layer/decoder.rs +139 -0
  92. data/vendor/wreq/src/client/layer/redirect/future.rs +270 -0
  93. data/vendor/wreq/src/client/layer/redirect/policy.rs +63 -0
  94. data/vendor/wreq/src/client/layer/redirect.rs +145 -0
  95. data/vendor/wreq/src/client/layer/retry/classify.rs +105 -0
  96. data/vendor/wreq/src/client/layer/retry/scope.rs +51 -0
  97. data/vendor/wreq/src/client/layer/retry.rs +151 -0
  98. data/vendor/wreq/src/client/layer/timeout/body.rs +233 -0
  99. data/vendor/wreq/src/client/layer/timeout/future.rs +90 -0
  100. data/vendor/wreq/src/client/layer/timeout.rs +177 -0
  101. data/vendor/wreq/src/client/layer.rs +15 -0
  102. data/vendor/wreq/src/client/multipart.rs +717 -0
  103. data/vendor/wreq/src/client/request.rs +818 -0
  104. data/vendor/wreq/src/client/response.rs +534 -0
  105. data/vendor/wreq/src/client/ws/json.rs +99 -0
  106. data/vendor/wreq/src/client/ws/message.rs +453 -0
  107. data/vendor/wreq/src/client/ws.rs +714 -0
  108. data/vendor/wreq/src/client.rs +27 -0
  109. data/vendor/wreq/src/config.rs +140 -0
  110. data/vendor/wreq/src/cookie.rs +579 -0
  111. data/vendor/wreq/src/dns/gai.rs +249 -0
  112. data/vendor/wreq/src/dns/hickory.rs +78 -0
  113. data/vendor/wreq/src/dns/resolve.rs +180 -0
  114. data/vendor/wreq/src/dns.rs +69 -0
  115. data/vendor/wreq/src/error.rs +502 -0
  116. data/vendor/wreq/src/ext.rs +398 -0
  117. data/vendor/wreq/src/hash.rs +143 -0
  118. data/vendor/wreq/src/header.rs +506 -0
  119. data/vendor/wreq/src/into_uri.rs +187 -0
  120. data/vendor/wreq/src/lib.rs +586 -0
  121. data/vendor/wreq/src/proxy/mac.rs +82 -0
  122. data/vendor/wreq/src/proxy/matcher.rs +806 -0
  123. data/vendor/wreq/src/proxy/uds.rs +66 -0
  124. data/vendor/wreq/src/proxy/win.rs +31 -0
  125. data/vendor/wreq/src/proxy.rs +569 -0
  126. data/vendor/wreq/src/redirect.rs +575 -0
  127. data/vendor/wreq/src/retry.rs +198 -0
  128. data/vendor/wreq/src/sync.rs +129 -0
  129. data/vendor/wreq/src/tls/conn/cache.rs +123 -0
  130. data/vendor/wreq/src/tls/conn/cert_compression.rs +125 -0
  131. data/vendor/wreq/src/tls/conn/ext.rs +82 -0
  132. data/vendor/wreq/src/tls/conn/macros.rs +34 -0
  133. data/vendor/wreq/src/tls/conn/service.rs +138 -0
  134. data/vendor/wreq/src/tls/conn.rs +681 -0
  135. data/vendor/wreq/src/tls/keylog/handle.rs +64 -0
  136. data/vendor/wreq/src/tls/keylog.rs +99 -0
  137. data/vendor/wreq/src/tls/options.rs +464 -0
  138. data/vendor/wreq/src/tls/x509/identity.rs +122 -0
  139. data/vendor/wreq/src/tls/x509/parser.rs +71 -0
  140. data/vendor/wreq/src/tls/x509/store.rs +228 -0
  141. data/vendor/wreq/src/tls/x509.rs +68 -0
  142. data/vendor/wreq/src/tls.rs +154 -0
  143. data/vendor/wreq/src/trace.rs +55 -0
  144. data/vendor/wreq/src/util.rs +122 -0
  145. data/vendor/wreq/tests/badssl.rs +228 -0
  146. data/vendor/wreq/tests/brotli.rs +350 -0
  147. data/vendor/wreq/tests/client.rs +1098 -0
  148. data/vendor/wreq/tests/connector_layers.rs +227 -0
  149. data/vendor/wreq/tests/cookie.rs +306 -0
  150. data/vendor/wreq/tests/deflate.rs +347 -0
  151. data/vendor/wreq/tests/emulation.rs +260 -0
  152. data/vendor/wreq/tests/gzip.rs +347 -0
  153. data/vendor/wreq/tests/layers.rs +261 -0
  154. data/vendor/wreq/tests/multipart.rs +165 -0
  155. data/vendor/wreq/tests/proxy.rs +438 -0
  156. data/vendor/wreq/tests/redirect.rs +629 -0
  157. data/vendor/wreq/tests/retry.rs +135 -0
  158. data/vendor/wreq/tests/support/delay_server.rs +117 -0
  159. data/vendor/wreq/tests/support/error.rs +16 -0
  160. data/vendor/wreq/tests/support/layer.rs +183 -0
  161. data/vendor/wreq/tests/support/mod.rs +9 -0
  162. data/vendor/wreq/tests/support/server.rs +232 -0
  163. data/vendor/wreq/tests/timeouts.rs +281 -0
  164. data/vendor/wreq/tests/unix_socket.rs +135 -0
  165. data/vendor/wreq/tests/upgrade.rs +98 -0
  166. data/vendor/wreq/tests/zstd.rs +559 -0
  167. metadata +225 -0
@@ -0,0 +1,453 @@
1
+ //! WebSocket message types and utilities
2
+ //!
3
+ //! This module provides WebSocket message types that wrap the underlying
4
+ //! tungstenite message implementation, offering a more ergonomic API
5
+ //! for working with WebSocket communications.
6
+
7
+ use std::{fmt, ops::Deref};
8
+
9
+ use bytes::Bytes;
10
+
11
+ use super::tungstenite;
12
+ use crate::Error;
13
+
14
+ /// UTF-8 wrapper for [Bytes].
15
+ ///
16
+ /// An [Utf8Bytes] is always guaranteed to contain valid UTF-8.
17
+ #[derive(Debug, Clone, PartialEq, Eq, Default)]
18
+ pub struct Utf8Bytes(pub(super) tungstenite::Utf8Bytes);
19
+
20
+ impl Utf8Bytes {
21
+ /// Creates from a static str.
22
+ #[inline]
23
+ pub const fn from_static(str: &'static str) -> Self {
24
+ Self(tungstenite::Utf8Bytes::from_static(str))
25
+ }
26
+
27
+ /// Returns as a string slice.
28
+ #[inline]
29
+ pub fn as_str(&self) -> &str {
30
+ self.0.as_str()
31
+ }
32
+ }
33
+
34
+ impl Deref for Utf8Bytes {
35
+ type Target = str;
36
+
37
+ /// ```
38
+ /// /// Example fn that takes a str slice
39
+ /// fn a(s: &str) {}
40
+ ///
41
+ /// let data = wreq::Utf8Bytes::from_static("foo123");
42
+ ///
43
+ /// // auto-deref as arg
44
+ /// a(&data);
45
+ ///
46
+ /// // deref to str methods
47
+ /// assert_eq!(data.len(), 6);
48
+ /// ```
49
+ #[inline]
50
+ fn deref(&self) -> &Self::Target {
51
+ self.as_str()
52
+ }
53
+ }
54
+
55
+ impl fmt::Display for Utf8Bytes {
56
+ #[inline]
57
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
58
+ f.write_str(self.as_str())
59
+ }
60
+ }
61
+
62
+ impl TryFrom<Bytes> for Utf8Bytes {
63
+ type Error = std::str::Utf8Error;
64
+
65
+ #[inline]
66
+ fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
67
+ Ok(Self(bytes.try_into()?))
68
+ }
69
+ }
70
+
71
+ impl TryFrom<Vec<u8>> for Utf8Bytes {
72
+ type Error = std::str::Utf8Error;
73
+
74
+ #[inline]
75
+ fn try_from(v: Vec<u8>) -> Result<Self, Self::Error> {
76
+ Ok(Self(v.try_into()?))
77
+ }
78
+ }
79
+
80
+ impl From<String> for Utf8Bytes {
81
+ #[inline]
82
+ fn from(s: String) -> Self {
83
+ Self(s.into())
84
+ }
85
+ }
86
+
87
+ impl From<&str> for Utf8Bytes {
88
+ #[inline]
89
+ fn from(s: &str) -> Self {
90
+ Self(s.into())
91
+ }
92
+ }
93
+
94
+ impl From<&String> for Utf8Bytes {
95
+ #[inline]
96
+ fn from(s: &String) -> Self {
97
+ Self(s.into())
98
+ }
99
+ }
100
+
101
+ impl From<Utf8Bytes> for Bytes {
102
+ #[inline]
103
+ fn from(Utf8Bytes(bytes): Utf8Bytes) -> Self {
104
+ bytes.into()
105
+ }
106
+ }
107
+
108
+ impl<T> PartialEq<T> for Utf8Bytes
109
+ where
110
+ for<'a> &'a str: PartialEq<T>,
111
+ {
112
+ /// ```
113
+ /// let payload = wreq::Utf8Bytes::from_static("foo123");
114
+ /// assert_eq!(payload, "foo123");
115
+ /// assert_eq!(payload, "foo123".to_string());
116
+ /// assert_eq!(payload, &"foo123".to_string());
117
+ /// assert_eq!(payload, std::borrow::Cow::from("foo123"));
118
+ /// ```
119
+ #[inline]
120
+ fn eq(&self, other: &T) -> bool {
121
+ self.as_str() == *other
122
+ }
123
+ }
124
+
125
+ /// Status code used to indicate why an endpoint is closing the WebSocket connection.
126
+ #[derive(Debug, Clone, Eq, PartialEq)]
127
+ pub struct CloseCode(pub(super) u16);
128
+
129
+ impl CloseCode {
130
+ //! Constants for [`CloseCode`]s.
131
+ //!
132
+ //! [`CloseCode`]: super::CloseCode
133
+
134
+ /// Indicates a normal closure, meaning that the purpose for which the connection was
135
+ /// established has been fulfilled.
136
+ pub const NORMAL: CloseCode = CloseCode(1000);
137
+
138
+ /// Indicates that an endpoint is "going away", such as a server going down or a browser having
139
+ /// navigated away from a page.
140
+ pub const AWAY: CloseCode = CloseCode(1001);
141
+
142
+ /// Indicates that an endpoint is terminating the connection due to a protocol error.
143
+ pub const PROTOCOL: CloseCode = CloseCode(1002);
144
+
145
+ /// Indicates that an endpoint is terminating the connection because it has received a type of
146
+ /// data that it cannot accept.
147
+ ///
148
+ /// For example, an endpoint MAY send this if it understands only text data, but receives a
149
+ /// binary message.
150
+ pub const UNSUPPORTED: CloseCode = CloseCode(1003);
151
+
152
+ /// Indicates that no status code was included in a closing frame.
153
+ pub const STATUS: CloseCode = CloseCode(1005);
154
+
155
+ /// Indicates an abnormal closure.
156
+ pub const ABNORMAL: CloseCode = CloseCode(1006);
157
+
158
+ /// Indicates that an endpoint is terminating the connection because it has received data
159
+ /// within a message that was not consistent with the type of the message.
160
+ ///
161
+ /// For example, an endpoint received non-UTF-8 RFC3629 data within a text message.
162
+ pub const INVALID: CloseCode = CloseCode(1007);
163
+
164
+ /// Indicates that an endpoint is terminating the connection because it has received a message
165
+ /// that violates its policy.
166
+ ///
167
+ /// This is a generic status code that can be returned when there is
168
+ /// no other more suitable status code (e.g., `UNSUPPORTED` or `SIZE`) or if there is a need to
169
+ /// hide specific details about the policy.
170
+ pub const POLICY: CloseCode = CloseCode(1008);
171
+
172
+ /// Indicates that an endpoint is terminating the connection because it has received a message
173
+ /// that is too big for it to process.
174
+ pub const SIZE: CloseCode = CloseCode(1009);
175
+
176
+ /// Indicates that an endpoint (client) is terminating the connection because the server
177
+ /// did not respond to extension negotiation correctly.
178
+ ///
179
+ /// Specifically, the client has expected the server to negotiate one or more extension(s),
180
+ /// but the server didn't return them in the response message of the WebSocket handshake.
181
+ /// The list of extensions that are needed should be given as the reason for closing.
182
+ /// Note that this status code is not used by the server,
183
+ /// because it can fail the WebSocket handshake instead.
184
+ pub const EXTENSION: CloseCode = CloseCode(1010);
185
+
186
+ /// Indicates that a server is terminating the connection because it encountered an unexpected
187
+ /// condition that prevented it from fulfilling the request.
188
+ pub const ERROR: CloseCode = CloseCode(1011);
189
+
190
+ /// Indicates that the server is restarting.
191
+ pub const RESTART: CloseCode = CloseCode(1012);
192
+
193
+ /// Indicates that the server is overloaded and the client should either connect to a different
194
+ /// IP (when multiple targets exist), or reconnect to the same IP when a user has performed an
195
+ /// action.
196
+ pub const AGAIN: CloseCode = CloseCode(1013);
197
+ }
198
+
199
+ impl From<CloseCode> for u16 {
200
+ #[inline]
201
+ fn from(code: CloseCode) -> u16 {
202
+ code.0
203
+ }
204
+ }
205
+
206
+ impl From<u16> for CloseCode {
207
+ #[inline]
208
+ fn from(code: u16) -> CloseCode {
209
+ CloseCode(code)
210
+ }
211
+ }
212
+
213
+ /// A struct representing the close command.
214
+ #[derive(Debug, Clone, Eq, PartialEq)]
215
+ pub struct CloseFrame {
216
+ /// The reason as a code.
217
+ pub code: CloseCode,
218
+ /// The reason as text string.
219
+ pub reason: Utf8Bytes,
220
+ }
221
+
222
+ /// A WebSocket message.
223
+ //
224
+ // This code comes from https://github.com/snapview/tungstenite-rs/blob/master/src/protocol/message.rs and is under following license:
225
+ // Copyright (c) 2017 Alexey Galakhov
226
+ // Copyright (c) 2016 Jason Housley
227
+ //
228
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
229
+ // of this software and associated documentation files (the "Software"), to deal
230
+ // in the Software without restriction, including without limitation the rights
231
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
232
+ // copies of the Software, and to permit persons to whom the Software is
233
+ // furnished to do so, subject to the following conditions:
234
+ //
235
+ // The above copyright notice and this permission notice shall be included in
236
+ // all copies or substantial portions of the Software.
237
+ //
238
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
239
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
240
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
241
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
242
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
243
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
244
+ // THE SOFTWARE.
245
+ #[derive(Debug, Eq, PartialEq, Clone)]
246
+ pub enum Message {
247
+ /// A text WebSocket message
248
+ Text(Utf8Bytes),
249
+ /// A binary WebSocket message
250
+ Binary(Bytes),
251
+ /// A ping message with the specified payload
252
+ ///
253
+ /// The payload here must have a length less than 125 bytes.
254
+ ///
255
+ /// Ping messages will be automatically responded to by the server, so you do not have to worry
256
+ /// about dealing with them yourself.
257
+ Ping(Bytes),
258
+ /// A pong message with the specified payload
259
+ ///
260
+ /// The payload here must have a length less than 125 bytes.
261
+ ///
262
+ /// Pong messages will be automatically sent to the client if a ping message is received, so
263
+ /// you do not have to worry about constructing them yourself unless you want to implement a
264
+ /// [unidirectional heartbeat](https://tools.ietf.org/html/rfc6455#section-5.5.3).
265
+ Pong(Bytes),
266
+ /// A close message with the optional close frame.
267
+ ///
268
+ /// You may "uncleanly" close a WebSocket connection at any time
269
+ /// by simply dropping the [`super::WebSocket`].
270
+ /// However, you may also use the graceful closing protocol, in which
271
+ /// 1. peer A sends a close frame, and does not send any further messages;
272
+ /// 2. peer B responds with a close frame, and does not send any further messages;
273
+ /// 3. peer A processes the remaining messages sent by peer B, before finally
274
+ /// 4. both peers close the connection.
275
+ ///
276
+ /// After sending a close frame,
277
+ /// you may still read messages,
278
+ /// but attempts to send another message will error.
279
+ /// After receiving a close frame,
280
+ /// wreq will automatically respond with a close frame if necessary
281
+ /// (you do not have to deal with this yourself).
282
+ /// Since no further messages will be received,
283
+ /// you may either do nothing
284
+ /// or explicitly drop the connection.
285
+ Close(Option<CloseFrame>),
286
+ }
287
+
288
+ impl Message {
289
+ /// Converts this `Message` into a `tungstenite::Message`.
290
+ ///
291
+ /// This method transforms the current `Message` instance into its corresponding
292
+ /// `tungstenite::Message` representation. This is useful when you need to work
293
+ /// with the `tungstenite` library directly.
294
+ ///
295
+ /// # Returns
296
+ ///
297
+ /// A `tungstenite::Message` instance that represents the current `Message`.
298
+ pub(super) fn into_tungstenite(self) -> tungstenite::Message {
299
+ match self {
300
+ Self::Text(text) => tungstenite::Message::Text(text.0),
301
+ Self::Binary(binary) => tungstenite::Message::Binary(binary),
302
+ Self::Ping(ping) => tungstenite::Message::Ping(ping),
303
+ Self::Pong(pong) => tungstenite::Message::Pong(pong),
304
+ Self::Close(Some(close)) => {
305
+ tungstenite::Message::Close(Some(tungstenite::protocol::CloseFrame {
306
+ code: tungstenite::protocol::frame::coding::CloseCode::from(close.code.0),
307
+ reason: close.reason.0,
308
+ }))
309
+ }
310
+ Self::Close(None) => tungstenite::Message::Close(None),
311
+ }
312
+ }
313
+
314
+ /// Converts a `tungstenite::Message` into an `Option<Message>`.
315
+ ///
316
+ /// This method transforms a given `tungstenite::Message` into its corresponding
317
+ /// `Message` representation. This is useful when you need to convert messages
318
+ /// received from the `tungstenite` library into the `Message` type used by this
319
+ /// library.
320
+ ///
321
+ /// # Arguments
322
+ ///
323
+ /// * `message` - The `tungstenite::Message` to convert.
324
+ ///
325
+ /// # Returns
326
+ ///
327
+ /// An `Option<Message>` instance that represents the given `tungstenite::Message`.
328
+ /// Returns `None` if the message is a `Frame` frame, as recommended by the
329
+ /// `tungstenite` maintainers.
330
+ pub(super) fn from_tungstenite(message: tungstenite::Message) -> Option<Self> {
331
+ match message {
332
+ tungstenite::Message::Text(text) => Some(Self::Text(Utf8Bytes(text))),
333
+ tungstenite::Message::Binary(binary) => Some(Self::Binary(binary)),
334
+ tungstenite::Message::Ping(ping) => Some(Self::Ping(ping)),
335
+ tungstenite::Message::Pong(pong) => Some(Self::Pong(pong)),
336
+ tungstenite::Message::Close(Some(close)) => Some(Self::Close(Some(CloseFrame {
337
+ code: CloseCode(close.code.into()),
338
+ reason: Utf8Bytes(close.reason),
339
+ }))),
340
+ tungstenite::Message::Close(None) => Some(Self::Close(None)),
341
+ // we can ignore `Frame` frames as recommended by the tungstenite maintainers
342
+ // https://github.com/snapview/tungstenite-rs/issues/268
343
+ tungstenite::Message::Frame(_) => None,
344
+ }
345
+ }
346
+
347
+ /// Consume the WebSocket and return it as binary data.
348
+ pub fn into_data(self) -> Bytes {
349
+ match self {
350
+ Self::Text(string) => Bytes::from(string),
351
+ Self::Binary(data) | Self::Ping(data) | Self::Pong(data) => data,
352
+ Self::Close(None) => Bytes::new(),
353
+ Self::Close(Some(frame)) => Bytes::from(frame.reason),
354
+ }
355
+ }
356
+
357
+ /// Attempt to consume the WebSocket message and convert it to a Utf8Bytes.
358
+ pub fn into_text(self) -> crate::Result<Utf8Bytes> {
359
+ match self {
360
+ Self::Text(string) => Ok(string),
361
+ Self::Binary(data) | Self::Ping(data) | Self::Pong(data) => {
362
+ Utf8Bytes::try_from(data).map_err(Error::decode)
363
+ }
364
+ Self::Close(None) => Ok(Utf8Bytes::default()),
365
+ Self::Close(Some(frame)) => Ok(frame.reason),
366
+ }
367
+ }
368
+
369
+ /// Attempt to get a &str from the WebSocket message,
370
+ /// this will try to convert binary data to utf8.
371
+ pub fn to_text(&self) -> crate::Result<&str> {
372
+ match *self {
373
+ Self::Text(ref string) => Ok(string.as_str()),
374
+ Self::Binary(ref data) | Self::Ping(ref data) | Self::Pong(ref data) => {
375
+ std::str::from_utf8(data).map_err(Error::decode)
376
+ }
377
+ Self::Close(None) => Ok(""),
378
+ Self::Close(Some(ref frame)) => Ok(&frame.reason),
379
+ }
380
+ }
381
+ }
382
+
383
+ impl Message {
384
+ /// Create a new text WebSocket message from a stringable.
385
+ pub fn text<S>(string: S) -> Message
386
+ where
387
+ S: Into<Utf8Bytes>,
388
+ {
389
+ Message::Text(string.into())
390
+ }
391
+
392
+ /// Create a new binary WebSocket message by converting to `Bytes`.
393
+ pub fn binary<B>(bin: B) -> Message
394
+ where
395
+ B: Into<Bytes>,
396
+ {
397
+ Message::Binary(bin.into())
398
+ }
399
+
400
+ /// Create a new ping WebSocket message by converting to `Bytes`.
401
+ pub fn ping<B>(bin: B) -> Message
402
+ where
403
+ B: Into<Bytes>,
404
+ {
405
+ Message::Ping(bin.into())
406
+ }
407
+
408
+ /// Create a new pong WebSocket message by converting to `Bytes`.
409
+ pub fn pong<B>(bin: B) -> Message
410
+ where
411
+ B: Into<Bytes>,
412
+ {
413
+ Message::Pong(bin.into())
414
+ }
415
+
416
+ /// Create a new close WebSocket message with an optional close frame.
417
+ pub fn close<C>(close: C) -> Message
418
+ where
419
+ C: Into<Option<CloseFrame>>,
420
+ {
421
+ Message::Close(close.into())
422
+ }
423
+ }
424
+
425
+ impl From<String> for Message {
426
+ fn from(string: String) -> Self {
427
+ Message::Text(string.into())
428
+ }
429
+ }
430
+
431
+ impl<'s> From<&'s str> for Message {
432
+ fn from(string: &'s str) -> Self {
433
+ Message::Text(string.into())
434
+ }
435
+ }
436
+
437
+ impl<'b> From<&'b [u8]> for Message {
438
+ fn from(data: &'b [u8]) -> Self {
439
+ Message::Binary(Bytes::copy_from_slice(data))
440
+ }
441
+ }
442
+
443
+ impl From<Vec<u8>> for Message {
444
+ fn from(data: Vec<u8>) -> Self {
445
+ Message::Binary(data.into())
446
+ }
447
+ }
448
+
449
+ impl From<Message> for Vec<u8> {
450
+ fn from(msg: Message) -> Self {
451
+ msg.into_data().to_vec()
452
+ }
453
+ }