soketto/
data.rs

1// Copyright (c) 2019 Parity Technologies (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0
4// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
5// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. All files in the project carrying such notice may not be copied,
7// modified, or distributed except according to those terms.
8
9//! Types describing various forms of payload data.
10
11use std::fmt;
12
13use crate::connection::CloseReason;
14
15/// Data received from the remote end.
16#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
17pub enum Incoming<'a> {
18	/// Text or binary data.
19	Data(Data),
20	/// Data sent with a PONG control frame.
21	Pong(&'a [u8]),
22	/// The other end closed the connection.
23	Closed(CloseReason),
24}
25
26impl Incoming<'_> {
27	/// Is this text or binary data?
28	pub fn is_data(&self) -> bool {
29		if let Incoming::Data(_) = self {
30			true
31		} else {
32			false
33		}
34	}
35
36	/// Is this a PONG?
37	pub fn is_pong(&self) -> bool {
38		if let Incoming::Pong(_) = self {
39			true
40		} else {
41			false
42		}
43	}
44
45	/// Is this text data?
46	pub fn is_text(&self) -> bool {
47		if let Incoming::Data(d) = self {
48			d.is_text()
49		} else {
50			false
51		}
52	}
53
54	/// Is this binary data?
55	pub fn is_binary(&self) -> bool {
56		if let Incoming::Data(d) = self {
57			d.is_binary()
58		} else {
59			false
60		}
61	}
62}
63
64#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
65pub enum Data {
66	/// Textual data (number of bytes).
67	Text(usize),
68	/// Binary data (number of bytes).
69	Binary(usize),
70}
71
72impl Data {
73	/// Is this text data?
74	pub fn is_text(&self) -> bool {
75		if let Data::Text(_) = self {
76			true
77		} else {
78			false
79		}
80	}
81
82	/// Is this binary data?
83	pub fn is_binary(&self) -> bool {
84		if let Data::Binary(_) = self {
85			true
86		} else {
87			false
88		}
89	}
90
91	/// The length of data (number of bytes).
92	pub fn len(&self) -> usize {
93		match self {
94			Data::Text(n) => *n,
95			Data::Binary(n) => *n,
96		}
97	}
98}
99
100/// Wrapper type which restricts the length of its byte slice to 125 bytes.
101#[derive(Debug)]
102pub struct ByteSlice125<'a>(&'a [u8]);
103
104/// Error, if converting to [`ByteSlice125`] fails.
105#[derive(Clone, Debug)]
106pub struct SliceTooLarge(());
107
108impl fmt::Display for SliceTooLarge {
109	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
110		f.write_str("Slice larger than 125 bytes")
111	}
112}
113
114impl std::error::Error for SliceTooLarge {}
115
116impl<'a> TryFrom<&'a [u8]> for ByteSlice125<'a> {
117	type Error = SliceTooLarge;
118
119	fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
120		if value.len() > 125 {
121			Err(SliceTooLarge(()))
122		} else {
123			Ok(ByteSlice125(value))
124		}
125	}
126}
127
128impl AsRef<[u8]> for ByteSlice125<'_> {
129	fn as_ref(&self) -> &[u8] {
130		self.0
131	}
132}