1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use async_tungstenite::tungstenite::{
protocol::{frame::coding::CloseCode, CloseFrame as TungsteniteCloseFrame},
Message as TungsteniteMessage,
};
use std::borrow::Cow;
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub struct CloseFrame<'a> {
pub code: u16,
pub reason: Cow<'a, str>,
}
impl<'a, T: Into<Cow<'a, str>>> From<(u16, T)> for CloseFrame<'a> {
fn from((code, reason): (u16, T)) -> Self {
Self {
code,
reason: reason.into(),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum Message {
Binary(Vec<u8>),
Close(Option<CloseFrame<'static>>),
Ping(Vec<u8>),
Pong(Vec<u8>),
Text(String),
}
impl Message {
pub(super) fn into_tungstenite(self) -> TungsteniteMessage {
match self {
Self::Binary(bytes) => TungsteniteMessage::Binary(bytes),
Self::Close(close) => {
TungsteniteMessage::Close(close.map(|close| TungsteniteCloseFrame {
code: CloseCode::from(close.code),
reason: close.reason,
}))
}
Self::Ping(bytes) => TungsteniteMessage::Ping(bytes),
Self::Pong(bytes) => TungsteniteMessage::Pong(bytes),
Self::Text(string) => TungsteniteMessage::Text(string),
}
}
}
#[cfg(test)]
mod tests {
use super::{CloseFrame, Message};
use static_assertions::{assert_fields, assert_impl_all};
use std::fmt::Debug;
assert_fields!(CloseFrame<'_>: code, reason);
assert_impl_all!(
CloseFrame<'_>:
Clone,
Debug,
Eq,
From<(u16, &'static str)>,
From<(u16, String)>,
PartialEq,
);
assert_impl_all!(Message: Clone, Debug, Eq, PartialEq);
}