Skip to content

Commit c772419

Browse files
committed
Switch websocket Message to a non-exhaustive enum
1 parent 9e74ff9 commit c772419

File tree

1 file changed

+68
-49
lines changed

1 file changed

+68
-49
lines changed

src/filters/ws.rs

+68-49
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ impl Stream for WebSocket {
207207

208208
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
209209
match ready!(Pin::new(&mut self.inner).poll_next(cx)) {
210-
Some(Ok(item)) => Poll::Ready(Some(Ok(Message { inner: item }))),
210+
Some(Ok(item)) => Poll::Ready(Some(Ok(Message::from_tungstenite(item)))),
211211
Some(Err(e)) => {
212212
tracing::debug!("websocket poll error: {}", e);
213213
Poll::Ready(Some(Err(crate::Error::new(e))))
@@ -231,7 +231,7 @@ impl Sink<Message> for WebSocket {
231231
}
232232

233233
fn start_send(mut self: Pin<&mut Self>, item: Message) -> Result<(), Self::Error> {
234-
match Pin::new(&mut self.inner).start_send(item.inner) {
234+
match Pin::new(&mut self.inner).start_send(item.into_tungstenite()) {
235235
Ok(()) => Ok(()),
236236
Err(e) => {
237237
tracing::debug!("websocket start_send error: {}", e);
@@ -265,34 +265,35 @@ impl fmt::Debug for WebSocket {
265265
}
266266

267267
/// A WebSocket message.
268-
///
269-
/// This will likely become a `non-exhaustive` enum in the future, once that
270-
/// language feature has stabilized.
271-
#[derive(Eq, PartialEq, Clone)]
272-
pub struct Message {
273-
inner: protocol::Message,
268+
#[derive(Debug, Eq, PartialEq, Clone)]
269+
#[non_exhaustive]
270+
pub enum Message {
271+
/// A websocket text data message
272+
Text(String),
273+
/// A websocket binary data message
274+
Binary(Vec<u8>),
275+
/// A websocket ping control message
276+
Ping(Vec<u8>),
277+
/// A websocket pong control message
278+
Pong(Vec<u8>),
279+
/// A websocket close control message
280+
Close(Option<(u16, Cow<'static, str>)>)
274281
}
275282

276283
impl Message {
277284
/// Construct a new Text `Message`.
278285
pub fn text<S: Into<String>>(s: S) -> Message {
279-
Message {
280-
inner: protocol::Message::text(s),
281-
}
286+
Message::Text(s.into())
282287
}
283288

284289
/// Construct a new Binary `Message`.
285290
pub fn binary<V: Into<Vec<u8>>>(v: V) -> Message {
286-
Message {
287-
inner: protocol::Message::binary(v),
288-
}
291+
Message::Binary(v.into())
289292
}
290293

291294
/// Construct a new Ping `Message`.
292295
pub fn ping<V: Into<Vec<u8>>>(v: V) -> Message {
293-
Message {
294-
inner: protocol::Message::Ping(v.into()),
295-
}
296+
Message::Ping(v.into())
296297
}
297298

298299
/// Construct a new Pong `Message`.
@@ -301,90 +302,108 @@ impl Message {
301302
/// automatically responds to the Ping messages it receives. Manual construction might still be useful in some cases
302303
/// like in tests or to send unidirectional heartbeats.
303304
pub fn pong<V: Into<Vec<u8>>>(v: V) -> Message {
304-
Message {
305-
inner: protocol::Message::Pong(v.into()),
306-
}
305+
Message::Pong(v.into())
307306
}
308307

309308
/// Construct the default Close `Message`.
310309
pub fn close() -> Message {
311-
Message {
312-
inner: protocol::Message::Close(None),
313-
}
310+
Message::Close(None)
314311
}
315312

316313
/// Construct a Close `Message` with a code and reason.
317314
pub fn close_with(code: impl Into<u16>, reason: impl Into<Cow<'static, str>>) -> Message {
318-
Message {
319-
inner: protocol::Message::Close(Some(protocol::frame::CloseFrame {
320-
code: protocol::frame::coding::CloseCode::from(code.into()),
321-
reason: reason.into(),
322-
})),
323-
}
315+
Message::Close(Some((code.into(), reason.into())))
324316
}
325317

326318
/// Returns true if this message is a Text message.
327319
pub fn is_text(&self) -> bool {
328-
self.inner.is_text()
320+
matches!(self, Message::Text(_))
329321
}
330322

331323
/// Returns true if this message is a Binary message.
332324
pub fn is_binary(&self) -> bool {
333-
self.inner.is_binary()
325+
matches!(self, Message::Binary(_))
334326
}
335327

336328
/// Returns true if this message a is a Close message.
337329
pub fn is_close(&self) -> bool {
338-
self.inner.is_close()
330+
matches!(self, Message::Close(_))
339331
}
340332

341333
/// Returns true if this message is a Ping message.
342334
pub fn is_ping(&self) -> bool {
343-
self.inner.is_ping()
335+
matches!(self, Message::Ping(_))
344336
}
345337

346338
/// Returns true if this message is a Pong message.
347339
pub fn is_pong(&self) -> bool {
348-
self.inner.is_pong()
340+
matches!(self, Message::Pong(_))
349341
}
350342

351343
/// Try to get the close frame (close code and reason)
352344
pub fn close_frame(&self) -> Option<(u16, &str)> {
353-
if let protocol::Message::Close(Some(ref close_frame)) = self.inner {
354-
Some((close_frame.code.into(), close_frame.reason.as_ref()))
345+
if let Message::Close(Some((code, reason))) = self {
346+
Some((*code, reason.as_ref()))
355347
} else {
356348
None
357349
}
358350
}
359351

360352
/// Try to get a reference to the string text, if this is a Text message.
361353
pub fn to_str(&self) -> Result<&str, ()> {
362-
match self.inner {
363-
protocol::Message::Text(ref s) => Ok(s),
354+
match self {
355+
Message::Text(s) => Ok(s),
364356
_ => Err(()),
365357
}
366358
}
367359

368360
/// Return the bytes of this message, if the message can contain data.
369361
pub fn as_bytes(&self) -> &[u8] {
370-
match self.inner {
371-
protocol::Message::Text(ref s) => s.as_bytes(),
372-
protocol::Message::Binary(ref v) => v,
373-
protocol::Message::Ping(ref v) => v,
374-
protocol::Message::Pong(ref v) => v,
375-
protocol::Message::Close(_) => &[],
362+
match self {
363+
Message::Text(string) => string.as_bytes(),
364+
Message::Binary(bytes) => bytes,
365+
Message::Ping(bytes) => bytes,
366+
Message::Pong(bytes) => bytes,
367+
Message::Close(_) => &[],
376368
}
377369
}
378370

379371
/// Destructure this message into binary data.
380372
pub fn into_bytes(self) -> Vec<u8> {
381-
self.inner.into_data()
373+
match self {
374+
Message::Text(string) => string.into_bytes(),
375+
Message::Binary(bytes) => bytes,
376+
Message::Ping(bytes) => bytes,
377+
Message::Pong(bytes) => bytes,
378+
Message::Close(Some((_, reason))) => reason.into_owned().into_bytes(),
379+
Message::Close(None) => Vec::new(),
380+
}
382381
}
383-
}
384382

385-
impl fmt::Debug for Message {
386-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
387-
fmt::Debug::fmt(&self.inner, f)
383+
fn from_tungstenite(message: protocol::Message) -> Self {
384+
use protocol::Message::*;
385+
386+
match message {
387+
Text(string) => Message::Text(string),
388+
Binary(bytes) => Message::Binary(bytes),
389+
Ping(bytes) => Message::Ping(bytes),
390+
Pong(bytes) => Message::Pong(bytes),
391+
Close(Some(protocol::CloseFrame { code, reason })) => Message::Close(Some((code.into(), reason))),
392+
Close(None) => Message::Close(None),
393+
}
394+
}
395+
396+
fn into_tungstenite(self) -> protocol::Message {
397+
use protocol::Message::*;
398+
399+
match self {
400+
Message::Text(string) => Text(string),
401+
Message::Binary(bytes) => Binary(bytes),
402+
Message::Ping(bytes) => Ping(bytes),
403+
Message::Pong(bytes) => Pong(bytes),
404+
Message::Close(Some((code, reason))) => Close(Some(protocol::CloseFrame { code: code.into(), reason })),
405+
Message::Close(None) => Close(None),
406+
}
388407
}
389408
}
390409

0 commit comments

Comments
 (0)