Skip to content

Commit 9b62a20

Browse files
move Write and Read definition to its own compat crate
since these two types are mimicking std extensions, it is better to denote them as compat
1 parent 8ab9ecf commit 9b62a20

File tree

3 files changed

+56
-99
lines changed

3 files changed

+56
-99
lines changed

src/compat.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use core::result::Result;
2+
// use core::pin::Pin;
3+
4+
pub trait Read<E> {
5+
fn read(&mut self, buf: &mut [u8]) -> Result<usize, E>;
6+
}
7+
8+
pub trait Write<E> {
9+
fn write_all(&mut self, buf: &[u8]) -> Result<(), E>;
10+
}
11+
12+
cfg_if::cfg_if! {
13+
if #[cfg(feature = "async")] {
14+
#[async_trait::async_trait]
15+
pub trait AsyncRead<E> {
16+
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, E>;
17+
}
18+
19+
#[async_trait::async_trait]
20+
pub trait AsyncWrite<E> {
21+
async fn write_all(&mut self, buf: &[u8]) -> Result<(), E>;
22+
}
23+
}
24+
}
25+
26+
cfg_if::cfg_if! {
27+
if #[cfg(feature = "std")] {
28+
impl Read<std::io::Error> for std::net::TcpStream {
29+
fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
30+
std::io::Read::read(self, buf)
31+
}
32+
}
33+
34+
impl Write<std::io::Error> for std::net::TcpStream {
35+
fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
36+
std::io::Write::write_all(self, buf)
37+
}
38+
}
39+
}
40+
}

src/framer.rs

Lines changed: 15 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -2,101 +2,17 @@
22
// This is the most common use case when working with websockets and is recommended due to the hand shaky nature of
33
// the protocol as well as the fact that an input buffer can contain multiple websocket frames or maybe only a fragment of one.
44
// This module allows you to work with discrete websocket frames rather than the multiple fragments you read off a stream.
5-
// NOTE: if you are using the standard library then you can use the built in Read and Write traits from std otherwise
6-
// you have to implement the Read and Write traits specified below
5+
// NOTE: if you are using the standard library then you can use the built in compat::Read and compat::Write traits from std otherwise
6+
// you have to implement the compat::Read and compat::Write traits specified below
77

88
use crate::{
9-
WebSocket, WebSocketCloseStatusCode, WebSocketContext, WebSocketOptions,
9+
compat, WebSocket, WebSocketCloseStatusCode, WebSocketContext, WebSocketOptions,
1010
WebSocketReceiveMessageType, WebSocketSendMessageType, WebSocketState, WebSocketSubProtocol,
1111
WebSocketType,
1212
};
1313
use core::{cmp::min, str::Utf8Error};
1414
use rand_core::RngCore;
1515

16-
pub trait Read<E> {
17-
fn read(&mut self, buf: &mut [u8]) -> Result<usize, E>;
18-
}
19-
20-
pub trait Write<E> {
21-
fn write_all(&mut self, buf: &[u8]) -> Result<(), E>;
22-
}
23-
24-
cfg_if::cfg_if! {
25-
if #[cfg(feature = "std")] {
26-
impl Read<std::io::Error> for std::net::TcpStream {
27-
fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
28-
std::io::Read::read(self, buf)
29-
}
30-
}
31-
32-
impl Write<std::io::Error> for std::net::TcpStream {
33-
fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
34-
std::io::Write::write_all(self, buf)
35-
}
36-
}
37-
}
38-
}
39-
40-
cfg_if::cfg_if! {
41-
if #[cfg(feature = "async")] {
42-
#[async_trait::async_trait]
43-
pub trait AsyncRead<E> {
44-
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, E>;
45-
}
46-
47-
#[async_trait::async_trait]
48-
pub trait AsyncWrite<E> {
49-
async fn write_all(&mut self, buf: &[u8]) -> Result<(), E>;
50-
}
51-
}
52-
}
53-
54-
cfg_if::cfg_if! {
55-
if #[cfg(feature = "tokio")] {
56-
#[async_trait::async_trait]
57-
impl AsyncRead<std::io::Error> for tokio::net::TcpStream {
58-
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
59-
tokio::io::AsyncReadExt::read(self, buf).await
60-
}
61-
}
62-
63-
#[async_trait::async_trait]
64-
impl AsyncWrite<std::io::Error> for tokio::net::TcpStream {
65-
async fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
66-
tokio::io::AsyncWriteExt::write_all(self, buf).await
67-
}
68-
}
69-
} else if #[cfg(feature = "smol")] {
70-
#[async_trait::async_trait]
71-
impl AsyncRead<std::io::Error> for smol::net::TcpStream {
72-
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
73-
smol::io::AsyncReadExt::read(self, buf).await
74-
}
75-
}
76-
77-
#[async_trait::async_trait]
78-
impl AsyncWrite<std::io::Error> for smol::net::TcpStream {
79-
async fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
80-
smol::io::AsyncWriteExt::write_all(self, buf).await
81-
}
82-
}
83-
} else if #[cfg(feature = "async-std")] {
84-
#[async_trait::async_trait]
85-
impl AsyncRead<std::io::Error> for async_std::net::TcpStream {
86-
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
87-
async_std::io::ReadExt::read(self, buf).await
88-
}
89-
}
90-
91-
#[async_trait::async_trait]
92-
impl AsyncWrite<std::io::Error> for async_std::net::TcpStream {
93-
async fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
94-
async_std::io::WriteExt::write_all(self, buf).await
95-
}
96-
}
97-
}
98-
}
99-
10016
pub enum ReadResult<'a> {
10117
Binary(&'a [u8]),
10218
Text(&'a str),
@@ -132,7 +48,7 @@ where
13248
{
13349
pub fn connect<E>(
13450
&mut self,
135-
stream: &mut (impl Read<E> + Write<E>),
51+
stream: &mut (impl compat::Read<E> + compat::Write<E>),
13652
websocket_options: &WebSocketOptions,
13753
) -> Result<Option<WebSocketSubProtocol>, FramerError<E>> {
13854
let (len, web_socket_key) = self
@@ -179,7 +95,7 @@ where
17995
{
18096
pub fn accept<E>(
18197
&mut self,
182-
stream: &mut impl Write<E>,
98+
stream: &mut impl compat::Write<E>,
18399
websocket_context: &WebSocketContext,
184100
) -> Result<(), FramerError<E>> {
185101
let len = self.accept_len(&websocket_context)?;
@@ -244,7 +160,7 @@ where
244160
// calling close on a websocket that has already been closed by the other party has no effect
245161
pub fn close<E>(
246162
&mut self,
247-
stream: &mut impl Write<E>,
163+
stream: &mut impl compat::Write<E>,
248164
close_status: WebSocketCloseStatusCode,
249165
status_description: Option<&str>,
250166
) -> Result<(), FramerError<E>> {
@@ -268,7 +184,7 @@ where
268184

269185
pub fn write<E>(
270186
&mut self,
271-
stream: &mut impl Write<E>,
187+
stream: &mut impl compat::Write<E>,
272188
message_type: WebSocketSendMessageType,
273189
end_of_message: bool,
274190
frame_buf: &[u8],
@@ -285,7 +201,7 @@ where
285201
// It will wait until the last fragmented frame has arrived.
286202
pub fn read<'b, E>(
287203
&mut self,
288-
stream: &mut (impl Read<E> + Write<E>),
204+
stream: &mut (impl compat::Read<E> + compat::Write<E>),
289205
frame_buf: &'b mut [u8],
290206
) -> Result<ReadResult<'b>, FramerError<E>> {
291207
loop {
@@ -365,7 +281,7 @@ where
365281

366282
fn send_back<E>(
367283
&mut self,
368-
stream: &mut impl Write<E>,
284+
stream: &mut impl compat::Write<E>,
369285
frame_buf: &'_ mut [u8],
370286
len_to: usize,
371287
send_message_type: WebSocketSendMessageType,
@@ -396,7 +312,7 @@ impl<'a, TRng> Framer<'a, TRng, crate::Client>
396312
where
397313
TRng: RngCore,
398314
{
399-
pub async fn connect_async<S: AsyncRead<E> + AsyncWrite<E> + Unpin, E>(
315+
pub async fn connect_async<S: compat::AsyncRead<E> + compat::AsyncWrite<E> + Unpin, E>(
400316
&mut self,
401317
stream: &mut S,
402318
websocket_options: &'a WebSocketOptions<'a>,
@@ -446,7 +362,7 @@ impl<'a, TRng> Framer<'a, TRng, crate::Server>
446362
where
447363
TRng: RngCore,
448364
{
449-
pub async fn accept_async<W: AsyncWrite<E> + Unpin, E>(
365+
pub async fn accept_async<W: compat::AsyncWrite<E> + Unpin, E>(
450366
&mut self,
451367
stream: &mut W,
452368
websocket_context: &WebSocketContext,
@@ -468,7 +384,7 @@ where
468384
TWebSocketType: WebSocketType,
469385
{
470386
// calling close on a websocket that has already been closed by the other party has no effect
471-
pub async fn close_async<W: AsyncWrite<E> + Unpin, E>(
387+
pub async fn close_async<W: compat::AsyncWrite<E> + Unpin, E>(
472388
&mut self,
473389
stream: &mut W,
474390
close_status: WebSocketCloseStatusCode,
@@ -482,7 +398,7 @@ where
482398
Ok(())
483399
}
484400

485-
pub async fn write_async<W: AsyncWrite<E> + Unpin, E>(
401+
pub async fn write_async<W: compat::AsyncWrite<E> + Unpin, E>(
486402
&mut self,
487403
stream: &mut W,
488404
message_type: WebSocketSendMessageType,
@@ -498,7 +414,7 @@ where
498414
Ok(())
499415
}
500416

501-
pub async fn read_async<'b, S: AsyncWrite<E> + AsyncRead<E> + Unpin, E>(
417+
pub async fn read_async<'b, S: compat::AsyncWrite<E> + compat::AsyncRead<E> + Unpin, E>(
502418
&mut self,
503419
stream: &mut S,
504420
frame_buf: &'b mut [u8],
@@ -580,7 +496,7 @@ where
580496
}
581497
}
582498

583-
async fn send_back_async<W: AsyncWrite<E> + Unpin, E>(
499+
async fn send_back_async<W: compat::AsyncWrite<E> + Unpin, E>(
584500
&mut self,
585501
stream: &mut W,
586502
frame_buf: &'_ mut [u8],

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub use self::random::EmptyRng;
2626

2727
// support for working with discrete websocket frames when using IO streams
2828
// start here!!
29+
pub mod compat;
2930
pub mod framer;
3031

3132
const MASK_KEY_LEN: usize = 4;

0 commit comments

Comments
 (0)