Skip to content

Commit b7e5e24

Browse files
committed
feat(engineioxide): use bytes::Bytes to represent a binary payload
This replaces the use of Vec<u8>.
1 parent 6504e49 commit b7e5e24

File tree

16 files changed

+84
-54
lines changed

16 files changed

+84
-54
lines changed

e2e/engineioxide/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ license.workspace = true
1212
publish = false
1313

1414
[dependencies]
15+
bytes.workspace = true
1516
engineioxide = { path = "../../engineioxide", default-features = false, features = [
1617
"tracing",
1718
] }

e2e/engineioxide/engineioxide.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use std::{sync::Arc, time::Duration};
44

5+
use bytes::Bytes;
56
use engineioxide::{
67
config::EngineIoConfig,
78
handler::EngineIoHandler,
@@ -32,7 +33,7 @@ impl EngineIoHandler for MyHandler {
3233
socket.emit(msg).ok();
3334
}
3435

35-
fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<Self::Data>>) {
36+
fn on_binary(&self, data: Bytes, socket: Arc<Socket<Self::Data>>) {
3637
println!("Ping pong binary message {:?}", data);
3738
socket.emit_binary(data).ok();
3839
}

engineioxide/Readme.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ engineioxide = { version = "0.3.0", features = ["v3"] }
2020

2121
## Basic example with axum :
2222
```rust
23+
use bytes::Bytes;
2324
use engineioxide::layer::EngineIoLayer;
2425
use engineioxide::handler::EngineIoHandler;
2526
use engineioxide::{Socket, DisconnectReason};
@@ -52,7 +53,7 @@ impl EngineIoHandler for MyHandler {
5253
fn on_message(&self, msg: String, socket: Arc<Socket<SocketState>>) {
5354
*socket.data.id.lock().unwrap() = msg; // bind a provided user id to a socket
5455
}
55-
fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<SocketState>>) { }
56+
fn on_binary(&self, data: Bytes, socket: Arc<Socket<SocketState>>) { }
5657
}
5758

5859
// Create a new engineio layer
@@ -64,4 +65,4 @@ let app = axum::Router::<()>::new()
6465

6566
// Spawn the axum server
6667

67-
```
68+
```

engineioxide/src/config.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! ## Configuration for the engine.io engine & transports
22
//! #### Example :
33
//! ```rust
4+
//! # use bytes::Bytes;
45
//! # use engineioxide::config::EngineIoConfig;
56
//! # use engineioxide::service::EngineIoService;
67
//! # use engineioxide::handler::EngineIoHandler;
@@ -15,7 +16,7 @@
1516
//! fn on_connect(&self, socket: Arc<Socket<()>>) { }
1617
//! fn on_disconnect(&self, socket: Arc<Socket<()>>, reason: DisconnectReason) { }
1718
//! fn on_message(&self, msg: String, socket: Arc<Socket<()>>) { }
18-
//! fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<()>>) { }
19+
//! fn on_binary(&self, data: Bytes, socket: Arc<Socket<()>>) { }
1920
//! }
2021
//!
2122
//! let config = EngineIoConfig::builder()
@@ -128,6 +129,7 @@ impl EngineIoConfigBuilder {
128129
///
129130
/// If the buffer if full the `emit()` method will return an error
130131
/// ```
132+
/// # use bytes::Bytes;
131133
/// # use engineioxide::{
132134
/// layer::EngineIoLayer,
133135
/// handler::EngineIoHandler,
@@ -152,7 +154,7 @@ impl EngineIoConfigBuilder {
152154
/// socket.emit(msg).unwrap();
153155
/// }
154156
///
155-
/// fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<()>>) {
157+
/// fn on_binary(&self, data: Bytes, socket: Arc<Socket<()>>) {
156158
/// println!("Ping pong binary message {:?}", data);
157159
/// socket.emit_binary(data).unwrap();
158160
/// }

engineioxide/src/engine.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ impl<H: EngineIoHandler> EngineIo<H> {
9595

9696
#[cfg(test)]
9797
mod tests {
98+
use bytes::Bytes;
9899
use http::Request;
99100

100101
use super::*;
@@ -118,7 +119,7 @@ mod tests {
118119
socket.emit(msg).ok();
119120
}
120121

121-
fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<Self::Data>>) {
122+
fn on_binary(&self, data: Bytes, socket: Arc<Socket<Self::Data>>) {
122123
println!("Ping pong binary message {:?}", data);
123124
socket.emit_binary(data).ok();
124125
}

engineioxide/src/handler.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! ## An [`EngineIoHandler`] to get event calls for any engine.io socket
22
//! #### Example :
33
//! ```rust
4+
//! # use bytes::Bytes;
45
//! # use engineioxide::service::EngineIoService;
56
//! # use engineioxide::handler::EngineIoHandler;
67
//! # use engineioxide::{Socket, DisconnectReason};
@@ -32,14 +33,16 @@
3233
//! fn on_message(&self, msg: String, socket: Arc<Socket<SocketState>>) {
3334
//! *socket.data.id.lock().unwrap() = msg; // bind a provided user id to a socket
3435
//! }
35-
//! fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<SocketState>>) { }
36+
//! fn on_binary(&self, data: Bytes, socket: Arc<Socket<SocketState>>) { }
3637
//! }
3738
//!
3839
//! // Create an engine io service with the given handler
3940
//! let svc = EngineIoService::new(MyHandler::default());
4041
//! ```
4142
use std::sync::Arc;
4243

44+
use bytes::Bytes;
45+
4346
use crate::socket::{DisconnectReason, Socket};
4447

4548
/// The [`EngineIoHandler`] trait can be implemented on any struct to handle socket events
@@ -59,7 +62,7 @@ pub trait EngineIoHandler: std::fmt::Debug + Send + Sync + 'static {
5962
fn on_message(&self, msg: String, socket: Arc<Socket<Self::Data>>);
6063

6164
/// Called when a binary message is received from the client.
62-
fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<Self::Data>>);
65+
fn on_binary(&self, data: Bytes, socket: Arc<Socket<Self::Data>>);
6366
}
6467

6568
impl<T: EngineIoHandler> EngineIoHandler for Arc<T> {
@@ -77,7 +80,7 @@ impl<T: EngineIoHandler> EngineIoHandler for Arc<T> {
7780
(**self).on_message(msg, socket)
7881
}
7982

80-
fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<Self::Data>>) {
83+
fn on_binary(&self, data: Bytes, socket: Arc<Socket<Self::Data>>) {
8184
(**self).on_binary(data, socket)
8285
}
8386
}

engineioxide/src/layer.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//!
33
//! #### Example with axum :
44
//! ```rust
5+
//! # use bytes::Bytes;
56
//! # use engineioxide::layer::EngineIoLayer;
67
//! # use engineioxide::handler::EngineIoHandler;
78
//! # use engineioxide::{Socket, DisconnectReason};
@@ -15,7 +16,7 @@
1516
//! fn on_connect(&self, socket: Arc<Socket<()>>) { }
1617
//! fn on_disconnect(&self, socket: Arc<Socket<()>>, reason: DisconnectReason) { }
1718
//! fn on_message(&self, msg: String, socket: Arc<Socket<()>>) { }
18-
//! fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<()>>) { }
19+
//! fn on_binary(&self, data: Bytes, socket: Arc<Socket<()>>) { }
1920
//! }
2021
//! // Create a new engineio layer
2122
//! let layer = EngineIoLayer::new(MyHandler);

engineioxide/src/packet.rs

+20-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use base64::{engine::general_purpose, Engine};
2+
use bytes::Bytes;
23
use serde::Serialize;
34

45
use crate::config::EngineIoConfig;
@@ -38,7 +39,7 @@ pub enum Packet {
3839
/// Or to a websocket binary frame when using websocket connection
3940
///
4041
/// When receiving, it is only used with polling connection, websocket use binary frame
41-
Binary(Vec<u8>), // Not part of the protocol, used internally
42+
Binary(Bytes), // Not part of the protocol, used internally
4243

4344
/// Binary packet used to send binary data to the client
4445
/// Converts to a String using base64 encoding when using polling connection
@@ -47,7 +48,7 @@ pub enum Packet {
4748
/// When receiving, it is only used with polling connection, websocket use binary frame
4849
///
4950
/// This is a special packet, excepionally specific to the V3 protocol.
50-
BinaryV3(Vec<u8>), // Not part of the protocol, used internally
51+
BinaryV3(Bytes), // Not part of the protocol, used internally
5152
}
5253

5354
impl Packet {
@@ -65,7 +66,7 @@ impl Packet {
6566
}
6667

6768
/// If the packet is a binary packet, it returns the binary data
68-
pub(crate) fn into_binary(self) -> Vec<u8> {
69+
pub(crate) fn into_binary(self) -> Bytes {
6970
match self {
7071
Packet::Binary(data) => data,
7172
Packet::BinaryV3(data) => data,
@@ -159,10 +160,16 @@ impl TryFrom<&str> for Packet {
159160
b'4' => Packet::Message(value[1..].to_string()),
160161
b'5' => Packet::Upgrade,
161162
b'6' => Packet::Noop,
162-
b'b' if value.as_bytes().get(1) == Some(&b'4') => {
163-
Packet::BinaryV3(general_purpose::STANDARD.decode(value[2..].as_bytes())?)
164-
}
165-
b'b' => Packet::Binary(general_purpose::STANDARD.decode(value[1..].as_bytes())?),
163+
b'b' if value.as_bytes().get(1) == Some(&b'4') => Packet::BinaryV3(
164+
general_purpose::STANDARD
165+
.decode(value[2..].as_bytes())?
166+
.into(),
167+
),
168+
b'b' => Packet::Binary(
169+
general_purpose::STANDARD
170+
.decode(value[1..].as_bytes())?
171+
.into(),
172+
),
166173
c => Err(Error::InvalidPacketType(Some(*c as char)))?,
167174
};
168175
Ok(res)
@@ -241,7 +248,7 @@ mod tests {
241248

242249
#[test]
243250
fn test_binary_packet() {
244-
let packet = Packet::Binary(vec![1, 2, 3]);
251+
let packet = Packet::Binary(vec![1, 2, 3].into());
245252
let packet_str: String = packet.try_into().unwrap();
246253
assert_eq!(packet_str, "bAQID");
247254
}
@@ -250,12 +257,12 @@ mod tests {
250257
fn test_binary_packet_deserialize() {
251258
let packet_str = "bAQID".to_string();
252259
let packet: Packet = packet_str.try_into().unwrap();
253-
assert_eq!(packet, Packet::Binary(vec![1, 2, 3]));
260+
assert_eq!(packet, Packet::Binary(vec![1, 2, 3].into()));
254261
}
255262

256263
#[test]
257264
fn test_binary_packet_v3() {
258-
let packet = Packet::BinaryV3(vec![1, 2, 3]);
265+
let packet = Packet::BinaryV3(vec![1, 2, 3].into());
259266
let packet_str: String = packet.try_into().unwrap();
260267
assert_eq!(packet_str, "b4AQID");
261268
}
@@ -264,7 +271,7 @@ mod tests {
264271
fn test_binary_packet_v3_deserialize() {
265272
let packet_str = "b4AQID".to_string();
266273
let packet: Packet = packet_str.try_into().unwrap();
267-
assert_eq!(packet, Packet::BinaryV3(vec![1, 2, 3]));
274+
assert_eq!(packet, Packet::BinaryV3(vec![1, 2, 3].into()));
268275
}
269276

270277
#[test]
@@ -310,11 +317,11 @@ mod tests {
310317
let packet = Packet::Noop;
311318
assert_eq!(packet.get_size_hint(false), 1);
312319

313-
let packet = Packet::Binary(vec![1, 2, 3]);
320+
let packet = Packet::Binary(vec![1, 2, 3].into());
314321
assert_eq!(packet.get_size_hint(false), 4);
315322
assert_eq!(packet.get_size_hint(true), 5);
316323

317-
let packet = Packet::BinaryV3(vec![1, 2, 3]);
324+
let packet = Packet::BinaryV3(vec![1, 2, 3].into());
318325
assert_eq!(packet.get_size_hint(false), 4);
319326
assert_eq!(packet.get_size_hint(true), 6);
320327
}

engineioxide/src/service/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! #### Example with a `hyper` standalone service :
55
//!
66
//! ```rust
7+
//! # use bytes::Bytes;
78
//! # use engineioxide::layer::EngineIoLayer;
89
//! # use engineioxide::handler::EngineIoHandler;
910
//! # use engineioxide::service::EngineIoService;
@@ -17,7 +18,7 @@
1718
//! fn on_connect(&self, socket: Arc<Socket<()>>) { }
1819
//! fn on_disconnect(&self, socket: Arc<Socket<()>>, reason: DisconnectReason) { }
1920
//! fn on_message(&self, msg: String, socket: Arc<Socket<()>>) { }
20-
//! fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<()>>) { }
21+
//! fn on_binary(&self, data: Bytes, socket: Arc<Socket<()>>) { }
2122
//! }
2223
//!
2324
//! // Create a new engine.io service that will return a 404 not found response for other requests

engineioxide/src/socket.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//!
88
//! #### Example :
99
//! ```rust
10+
//! # use bytes::Bytes;
1011
//! # use engineioxide::service::EngineIoService;
1112
//! # use engineioxide::handler::EngineIoHandler;
1213
//! # use engineioxide::{Socket, DisconnectReason};
@@ -48,7 +49,7 @@
4849
//! fn on_message(&self, msg: String, socket: Arc<Socket<SocketState>>) {
4950
//! *socket.data.id.lock().unwrap() = msg; // bind a provided user id to a socket
5051
//! }
51-
//! fn on_binary(&self, data: Vec<u8>, socket: Arc<Socket<SocketState>>) { }
52+
//! fn on_binary(&self, data: Bytes, socket: Arc<Socket<SocketState>>) { }
5253
//! }
5354
//!
5455
//! let svc = EngineIoService::new(MyHandler::default());
@@ -61,6 +62,7 @@ use std::{
6162
time::Duration,
6263
};
6364

65+
use bytes::Bytes;
6466
use http::request::Parts;
6567
use tokio::{
6668
sync::{
@@ -128,7 +130,7 @@ impl Permit<'_> {
128130
}
129131
/// Consume the permit and emit a binary message to the client.
130132
#[inline]
131-
pub fn emit_binary(self, data: Vec<u8>) {
133+
pub fn emit_binary(self, data: Bytes) {
132134
self.inner.send(Packet::Binary(data));
133135
}
134136
}
@@ -439,7 +441,7 @@ where
439441
/// If the transport is in polling mode, the message is buffered and sent as a text frame **encoded in base64** to the next polling request.
440442
///
441443
/// ⚠️ If the buffer is full or the socket is disconnected, an error will be returned with the original data
442-
pub fn emit_binary(&self, data: Vec<u8>) -> Result<(), TrySendError<Vec<u8>>> {
444+
pub fn emit_binary(&self, data: Bytes) -> Result<(), TrySendError<Bytes>> {
443445
if self.protocol == ProtocolVersion::V3 {
444446
self.send(Packet::BinaryV3(data))
445447
} else {

engineioxide/src/transport/polling/payload/decoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ where
205205
STRING_PACKET_IDENTIFIER_V3 => std::str::from_utf8(&packet_buf)
206206
.map_err(|_| Error::InvalidPacketLength)
207207
.and_then(Packet::try_from), // Convert the packet buffer to a Packet object
208-
BINARY_PACKET_IDENTIFIER_V3 => Ok(Packet::BinaryV3(packet_buf)),
208+
BINARY_PACKET_IDENTIFIER_V3 => Ok(Packet::BinaryV3(packet_buf.into())),
209209
_ => Err(Error::InvalidPacketLength),
210210
};
211211

0 commit comments

Comments
 (0)