razer_ws/
communication.rs1use std::borrow::Cow;
2use std::convert::Into;
3
4use mio;
5use mio::Token;
6use mio_extras::timer::Timeout;
7use url;
8
9use io::ALL;
10use message;
11use protocol::CloseCode;
12use result::{Error, Result};
13use std::cmp::PartialEq;
14use std::hash::{Hash, Hasher};
15use std::fmt;
16
17#[derive(Debug, Clone)]
18pub enum Signal {
19 Message(message::Message),
20 Close(CloseCode, Cow<'static, str>),
21 Ping(Vec<u8>),
22 Pong(Vec<u8>),
23 Connect(url::Url),
24 Shutdown,
25 Timeout { delay: u64, token: Token },
26 Cancel(Timeout),
27}
28
29#[derive(Debug, Clone)]
30pub struct Command {
31 token: Token,
32 signal: Signal,
33 connection_id: u32,
34}
35
36impl Command {
37 pub fn token(&self) -> Token {
38 self.token
39 }
40
41 pub fn into_signal(self) -> Signal {
42 self.signal
43 }
44
45 pub fn connection_id(&self) -> u32 {
46 self.connection_id
47 }
48}
49
50#[derive(Clone)]
53pub struct Sender {
54 token: Token,
55 channel: mio::channel::SyncSender<Command>,
56 connection_id: u32,
57}
58
59impl fmt::Debug for Sender {
60 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61 write!(f,
62 "Sender {{ token: {:?}, channel: mio::channel::SyncSender<Command>, connection_id: {:?} }}",
63 self.token, self.connection_id)
64 }
65}
66
67impl PartialEq for Sender {
68 fn eq(&self, other: &Sender) -> bool {
69 self.token == other.token && self.connection_id == other.connection_id
70 }
71}
72
73impl Eq for Sender { }
74
75impl Hash for Sender {
76 fn hash<H: Hasher>(&self, state: &mut H) {
77 self.connection_id.hash(state);
78 self.token.hash(state);
79 }
80}
81
82
83impl Sender {
84 #[doc(hidden)]
85 #[inline]
86 pub fn new(
87 token: Token,
88 channel: mio::channel::SyncSender<Command>,
89 connection_id: u32,
90 ) -> Sender {
91 Sender {
92 token,
93 channel,
94 connection_id,
95 }
96 }
97
98 #[inline]
100 pub fn token(&self) -> Token {
101 self.token
102 }
103
104 #[inline]
106 pub fn connection_id(&self) -> u32 {
107 self.connection_id
108 }
109
110 #[inline]
112 pub fn change_token(
113 &mut self,
114 token: Token,
115 id: u32
116 ) {
117 self.token = token;
118 self.connection_id = id;
119 }
120
121 #[inline]
123 pub fn send<M>(&self, msg: M) -> Result<()>
124 where
125 M: Into<message::Message>,
126 {
127 self.channel
128 .send(Command {
129 token: self.token,
130 signal: Signal::Message(msg.into()),
131 connection_id: self.connection_id,
132 })
133 .map_err(Error::from)
134 }
135
136 #[inline]
144 pub fn broadcast<M>(&self, msg: M) -> Result<()>
145 where
146 M: Into<message::Message>,
147 {
148 self.channel
149 .send(Command {
150 token: ALL,
151 signal: Signal::Message(msg.into()),
152 connection_id: self.connection_id,
153 })
154 .map_err(Error::from)
155 }
156
157 #[inline]
159 pub fn close(&self, code: CloseCode) -> Result<()> {
160 self.channel
161 .send(Command {
162 token: self.token,
163 signal: Signal::Close(code, "".into()),
164 connection_id: self.connection_id,
165 })
166 .map_err(Error::from)
167 }
168
169 #[inline]
171 pub fn close_with_reason<S>(&self, code: CloseCode, reason: S) -> Result<()>
172 where
173 S: Into<Cow<'static, str>>,
174 {
175 self.channel
176 .send(Command {
177 token: self.token,
178 signal: Signal::Close(code, reason.into()),
179 connection_id: self.connection_id,
180 })
181 .map_err(Error::from)
182 }
183
184 #[inline]
186 pub fn ping(&self, data: Vec<u8>) -> Result<()> {
187 self.channel
188 .send(Command {
189 token: self.token,
190 signal: Signal::Ping(data),
191 connection_id: self.connection_id,
192 })
193 .map_err(Error::from)
194 }
195
196 #[inline]
198 pub fn pong(&self, data: Vec<u8>) -> Result<()> {
199 self.channel
200 .send(Command {
201 token: self.token,
202 signal: Signal::Pong(data),
203 connection_id: self.connection_id,
204 })
205 .map_err(Error::from)
206 }
207
208 #[inline]
210 pub fn connect(&self, url: url::Url) -> Result<()> {
211 self.channel
212 .send(Command {
213 token: self.token,
214 signal: Signal::Connect(url),
215 connection_id: self.connection_id,
216 })
217 .map_err(Error::from)
218 }
219
220 #[inline]
222 pub fn shutdown(&self) -> Result<()> {
223 self.channel
224 .send(Command {
225 token: self.token,
226 signal: Signal::Shutdown,
227 connection_id: self.connection_id,
228 })
229 .map_err(Error::from)
230 }
231
232 #[inline]
235 pub fn timeout(&self, ms: u64, token: Token) -> Result<()> {
236 self.channel
237 .send(Command {
238 token: self.token,
239 signal: Signal::Timeout { delay: ms, token },
240 connection_id: self.connection_id,
241 })
242 .map_err(Error::from)
243 }
244
245 #[inline]
251 pub fn cancel(&self, timeout: Timeout) -> Result<()> {
252 self.channel
253 .send(Command {
254 token: self.token,
255 signal: Signal::Cancel(timeout),
256 connection_id: self.connection_id,
257 })
258 .map_err(Error::from)
259 }
260}