1use std::borrow::Cow;
2use std::convert::Into;
3
4use mio;
5use mio::Token;
6use url;
7
8use io::ALL;
9use message;
10use protocol::CloseCode;
11use result::{Error, Result};
12use std::cmp::PartialEq;
13
14#[derive(Debug, Clone)]
15pub enum Signal {
16 Message(message::Message),
17 Close(CloseCode, Cow<'static, str>),
18 Ping(Vec<u8>),
19 Pong(Vec<u8>),
20 Connect(url::Url),
21 Shutdown,
22 Timeout { delay: u64, token: Token },
23 Cancel(mio::timer::Timeout),
24}
25
26#[derive(Debug, Clone)]
27pub struct Command {
28 token: Token,
29 signal: Signal,
30 connection_id: u32,
31}
32
33impl Command {
34 pub fn token(&self) -> Token {
35 self.token
36 }
37
38 pub fn into_signal(self) -> Signal {
39 self.signal
40 }
41
42 pub fn connection_id(&self) -> u32 {
43 self.connection_id
44 }
45}
46
47#[derive(Clone)]
50pub struct Sender {
51 token: Token,
52 channel: mio::channel::SyncSender<Command>,
53 connection_id: u32,
54}
55
56impl PartialEq for Sender {
57 fn eq(&self, other: &Sender) -> bool {
58 self.token == other.token && self.connection_id == other.connection_id
59 }
60}
61
62impl Sender {
63 #[doc(hidden)]
64 #[inline]
65 pub fn new(
66 token: Token,
67 channel: mio::channel::SyncSender<Command>,
68 connection_id: u32,
69 ) -> Sender {
70 Sender {
71 token: token,
72 channel: channel,
73 connection_id: connection_id,
74 }
75 }
76
77 #[inline]
79 pub fn token(&self) -> Token {
80 self.token
81 }
82
83 #[inline]
85 pub fn connection_id(&self) -> u32 {
86 self.connection_id
87 }
88
89 #[inline]
91 pub fn send<M>(&self, msg: M) -> Result<()>
92 where
93 M: Into<message::Message>,
94 {
95 self.channel
96 .send(Command {
97 token: self.token,
98 signal: Signal::Message(msg.into()),
99 connection_id: self.connection_id,
100 })
101 .map_err(Error::from)
102 }
103
104 #[inline]
112 pub fn broadcast<M>(&self, msg: M) -> Result<()>
113 where
114 M: Into<message::Message>,
115 {
116 self.channel
117 .send(Command {
118 token: ALL,
119 signal: Signal::Message(msg.into()),
120 connection_id: self.connection_id,
121 })
122 .map_err(Error::from)
123 }
124
125 #[inline]
127 pub fn close(&self, code: CloseCode) -> Result<()> {
128 self.channel
129 .send(Command {
130 token: self.token,
131 signal: Signal::Close(code, "".into()),
132 connection_id: self.connection_id,
133 })
134 .map_err(Error::from)
135 }
136
137 #[inline]
139 pub fn close_with_reason<S>(&self, code: CloseCode, reason: S) -> Result<()>
140 where
141 S: Into<Cow<'static, str>>,
142 {
143 self.channel
144 .send(Command {
145 token: self.token,
146 signal: Signal::Close(code, reason.into()),
147 connection_id: self.connection_id,
148 })
149 .map_err(Error::from)
150 }
151
152 #[inline]
154 pub fn ping(&self, data: Vec<u8>) -> Result<()> {
155 self.channel
156 .send(Command {
157 token: self.token,
158 signal: Signal::Ping(data),
159 connection_id: self.connection_id,
160 })
161 .map_err(Error::from)
162 }
163
164 #[inline]
166 pub fn pong(&self, data: Vec<u8>) -> Result<()> {
167 self.channel
168 .send(Command {
169 token: self.token,
170 signal: Signal::Pong(data),
171 connection_id: self.connection_id,
172 })
173 .map_err(Error::from)
174 }
175
176 #[inline]
178 pub fn connect(&self, url: url::Url) -> Result<()> {
179 self.channel
180 .send(Command {
181 token: self.token,
182 signal: Signal::Connect(url),
183 connection_id: self.connection_id,
184 })
185 .map_err(Error::from)
186 }
187
188 #[inline]
190 pub fn shutdown(&self) -> Result<()> {
191 self.channel
192 .send(Command {
193 token: self.token,
194 signal: Signal::Shutdown,
195 connection_id: self.connection_id,
196 })
197 .map_err(Error::from)
198 }
199
200 #[inline]
203 pub fn timeout(&self, ms: u64, token: Token) -> Result<()> {
204 self.channel
205 .send(Command {
206 token: self.token,
207 signal: Signal::Timeout {
208 delay: ms,
209 token: token,
210 },
211 connection_id: self.connection_id,
212 })
213 .map_err(Error::from)
214 }
215
216 #[inline]
222 pub fn cancel(&self, timeout: mio::timer::Timeout) -> Result<()> {
223 self.channel
224 .send(Command {
225 token: self.token,
226 signal: Signal::Cancel(timeout),
227 connection_id: self.connection_id,
228 })
229 .map_err(Error::from)
230 }
231}