1use super::frame::{CloseFrame, Frame};
2use crate::{
3 error::{CapacityError, Error, Result},
4 protocol::frame::Utf8Bytes,
5};
6use std::{fmt, result::Result as StdResult, str};
7
8mod string_collect {
9 use utf8::DecodeError;
10
11 use crate::error::{Error, Result};
12
13 #[derive(Debug)]
14 pub struct StringCollector {
15 data: String,
16 incomplete: Option<utf8::Incomplete>,
17 }
18
19 impl StringCollector {
20 pub fn new() -> Self {
21 StringCollector { data: String::new(), incomplete: None }
22 }
23
24 pub fn len(&self) -> usize {
25 self.data
26 .len()
27 .saturating_add(self.incomplete.map(|i| i.buffer_len as usize).unwrap_or(0))
28 }
29
30 pub fn extend<T: AsRef<[u8]>>(&mut self, tail: T) -> Result<()> {
31 let mut input: &[u8] = tail.as_ref();
32
33 if let Some(mut incomplete) = self.incomplete.take() {
34 if let Some((result, rest)) = incomplete.try_complete(input) {
35 input = rest;
36 match result {
37 Ok(text) => self.data.push_str(text),
38 Err(result_bytes) => {
39 return Err(Error::Utf8(String::from_utf8_lossy(result_bytes).into()))
40 }
41 }
42 } else {
43 input = &[];
44 self.incomplete = Some(incomplete);
45 }
46 }
47
48 if !input.is_empty() {
49 match utf8::decode(input) {
50 Ok(text) => {
51 self.data.push_str(text);
52 Ok(())
53 }
54 Err(DecodeError::Incomplete { valid_prefix, incomplete_suffix }) => {
55 self.data.push_str(valid_prefix);
56 self.incomplete = Some(incomplete_suffix);
57 Ok(())
58 }
59 Err(DecodeError::Invalid { valid_prefix, invalid_sequence, .. }) => {
60 self.data.push_str(valid_prefix);
61 Err(Error::Utf8(String::from_utf8_lossy(invalid_sequence).into()))
62 }
63 }
64 } else {
65 Ok(())
66 }
67 }
68
69 pub fn into_string(self) -> Result<String> {
70 if let Some(incomplete) = self.incomplete {
71 Err(Error::Utf8(format!("incomplete string: {incomplete:?}")))
72 } else {
73 Ok(self.data)
74 }
75 }
76 }
77}
78
79use self::string_collect::StringCollector;
80use bytes::Bytes;
81
82#[derive(Debug)]
84pub struct IncompleteMessage {
85 collector: IncompleteMessageCollector,
86 #[cfg(feature = "deflate")]
87 compressed: bool,
88}
89
90#[derive(Debug)]
91enum IncompleteMessageCollector {
92 Text(StringCollector),
93 Binary(Vec<u8>),
94}
95
96impl IncompleteMessage {
97 pub fn new(message_type: MessageType) -> Self {
99 IncompleteMessage {
100 collector: match message_type {
101 MessageType::Binary => IncompleteMessageCollector::Binary(Vec::new()),
102 MessageType::Text => IncompleteMessageCollector::Text(StringCollector::new()),
103 },
104 #[cfg(feature = "deflate")]
105 compressed: false,
106 }
107 }
108
109 #[cfg(feature = "deflate")]
111 pub fn new_compressed(message_type: MessageType) -> Self {
112 IncompleteMessage {
113 collector: match message_type {
114 MessageType::Binary => IncompleteMessageCollector::Binary(Vec::new()),
115 MessageType::Text => IncompleteMessageCollector::Text(StringCollector::new()),
116 },
117 compressed: true,
118 }
119 }
120
121 pub fn compressed(&self) -> bool {
122 #[cfg(feature = "deflate")]
123 return self.compressed;
124 #[cfg(not(feature = "deflate"))]
125 return false;
126 }
127
128 pub fn len(&self) -> usize {
130 match self.collector {
131 IncompleteMessageCollector::Text(ref t) => t.len(),
132 IncompleteMessageCollector::Binary(ref b) => b.len(),
133 }
134 }
135
136 pub fn extend<T: AsRef<[u8]>>(&mut self, tail: T, size_limit: Option<usize>) -> Result<()> {
138 let max_size = size_limit.unwrap_or_else(usize::max_value);
141 let my_size = self.len();
142 let portion_size = tail.as_ref().len();
143 if my_size > max_size || portion_size > max_size - my_size {
145 return Err(Error::Capacity(CapacityError::MessageTooLong {
146 size: my_size + portion_size,
147 max_size,
148 }));
149 }
150
151 match self.collector {
152 IncompleteMessageCollector::Binary(ref mut v) => {
153 v.extend(tail.as_ref());
154 Ok(())
155 }
156 IncompleteMessageCollector::Text(ref mut t) => t.extend(tail),
157 }
158 }
159
160 pub fn complete(self) -> Result<Message> {
162 match self.collector {
163 IncompleteMessageCollector::Binary(v) => Ok(Message::Binary(v.into())),
164 IncompleteMessageCollector::Text(t) => {
165 let text = t.into_string()?;
166 Ok(Message::text(text))
167 }
168 }
169 }
170}
171
172pub enum MessageType {
174 Text,
175 Binary,
176}
177
178#[derive(Debug, Eq, PartialEq, Clone)]
180pub enum Message {
181 Text(Utf8Bytes),
183 Binary(Bytes),
185 Ping(Bytes),
189 Pong(Bytes),
193 Close(Option<CloseFrame>),
195 Frame(Frame),
197}
198
199impl Message {
200 pub fn text<S>(string: S) -> Message
202 where
203 S: Into<Utf8Bytes>,
204 {
205 Message::Text(string.into())
206 }
207
208 pub fn binary<B>(bin: B) -> Message
210 where
211 B: Into<Bytes>,
212 {
213 Message::Binary(bin.into())
214 }
215
216 pub fn is_text(&self) -> bool {
218 matches!(*self, Message::Text(_))
219 }
220
221 pub fn is_binary(&self) -> bool {
223 matches!(*self, Message::Binary(_))
224 }
225
226 pub fn is_ping(&self) -> bool {
228 matches!(*self, Message::Ping(_))
229 }
230
231 pub fn is_pong(&self) -> bool {
233 matches!(*self, Message::Pong(_))
234 }
235
236 pub fn is_close(&self) -> bool {
238 matches!(*self, Message::Close(_))
239 }
240
241 pub fn len(&self) -> usize {
243 match *self {
244 Message::Text(ref string) => string.len(),
245 Message::Binary(ref data) | Message::Ping(ref data) | Message::Pong(ref data) => {
246 data.len()
247 }
248 Message::Close(ref data) => data.as_ref().map(|d| d.reason.len()).unwrap_or(0),
249 Message::Frame(ref frame) => frame.len(),
250 }
251 }
252
253 pub fn is_empty(&self) -> bool {
256 self.len() == 0
257 }
258
259 pub fn into_data(self) -> Bytes {
261 match self {
262 Message::Text(utf8) => utf8.into(),
263 Message::Binary(data) | Message::Ping(data) | Message::Pong(data) => data,
264 Message::Close(None) => <_>::default(),
265 Message::Close(Some(frame)) => frame.reason.into(),
266 Message::Frame(frame) => frame.into_payload(),
267 }
268 }
269
270 pub fn into_text(self) -> Result<Utf8Bytes> {
272 match self {
273 Message::Text(txt) => Ok(txt),
274 Message::Binary(data) | Message::Ping(data) | Message::Pong(data) => {
275 Ok(data.try_into()?)
276 }
277 Message::Close(None) => Ok(<_>::default()),
278 Message::Close(Some(frame)) => Ok(frame.reason),
279 Message::Frame(frame) => Ok(frame.into_text()?),
280 }
281 }
282
283 pub fn to_text(&self) -> Result<&str> {
286 match *self {
287 Message::Text(ref string) => Ok(string.as_str()),
288 Message::Binary(ref data) | Message::Ping(ref data) | Message::Pong(ref data) => {
289 Ok(str::from_utf8(data)?)
290 }
291 Message::Close(None) => Ok(""),
292 Message::Close(Some(ref frame)) => Ok(&frame.reason),
293 Message::Frame(ref frame) => Ok(frame.to_text()?),
294 }
295 }
296}
297
298impl From<String> for Message {
299 #[inline]
300 fn from(string: String) -> Self {
301 Message::text(string)
302 }
303}
304
305impl<'s> From<&'s str> for Message {
306 #[inline]
307 fn from(string: &'s str) -> Self {
308 Message::text(string)
309 }
310}
311
312impl<'b> From<&'b [u8]> for Message {
313 #[inline]
314 fn from(data: &'b [u8]) -> Self {
315 Message::binary(Bytes::copy_from_slice(data))
316 }
317}
318
319impl From<Bytes> for Message {
320 fn from(data: Bytes) -> Self {
321 Message::binary(data)
322 }
323}
324
325impl From<Vec<u8>> for Message {
326 #[inline]
327 fn from(data: Vec<u8>) -> Self {
328 Message::binary(data)
329 }
330}
331
332impl From<Message> for Bytes {
333 #[inline]
334 fn from(message: Message) -> Self {
335 message.into_data()
336 }
337}
338
339impl fmt::Display for Message {
340 fn fmt(&self, f: &mut fmt::Formatter) -> StdResult<(), fmt::Error> {
341 if let Ok(string) = self.to_text() {
342 write!(f, "{string}")
343 } else {
344 write!(f, "Binary Data<length={}>", self.len())
345 }
346 }
347}
348
349#[cfg(test)]
350mod tests {
351 use super::*;
352
353 #[test]
354 fn display() {
355 let t = Message::text("test".to_owned());
356 assert_eq!(t.to_string(), "test".to_owned());
357
358 let bin = Message::binary(vec![0, 1, 3, 4, 241]);
359 assert_eq!(bin.to_string(), "Binary Data<length=5>".to_owned());
360 }
361
362 #[test]
363 fn binary_convert() {
364 let bin = [6u8, 7, 8, 9, 10, 241];
365 let msg = Message::from(&bin[..]);
366 assert!(msg.is_binary());
367 assert!(msg.into_text().is_err());
368 }
369
370 #[test]
371 fn binary_convert_bytes() {
372 let bin = Bytes::from_iter([6u8, 7, 8, 9, 10, 241]);
373 let msg = Message::from(bin);
374 assert!(msg.is_binary());
375 assert!(msg.into_text().is_err());
376 }
377
378 #[test]
379 fn binary_convert_vec() {
380 let bin = vec![6u8, 7, 8, 9, 10, 241];
381 let msg = Message::from(bin);
382 assert!(msg.is_binary());
383 assert!(msg.into_text().is_err());
384 }
385
386 #[test]
387 fn binary_convert_into_bytes() {
388 let bin = vec![6u8, 7, 8, 9, 10, 241];
389 let bin_copy = bin.clone();
390 let msg = Message::from(bin);
391 let serialized: Bytes = msg.into();
392 assert_eq!(bin_copy, serialized);
393 }
394
395 #[test]
396 fn text_convert() {
397 let s = "kiwotsukete";
398 let msg = Message::from(s);
399 assert!(msg.is_text());
400 }
401}