Skip to content

Commit 5ad34ca

Browse files
remove async framework dependencies, add example compat converter to each async example
1 parent 9b62a20 commit 5ad34ca

File tree

5 files changed

+259
-33
lines changed

5 files changed

+259
-33
lines changed

Cargo.toml

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,16 @@ categories = ["embedded", "no-std", "network-programming"]
1111
readme = "README.md"
1212

1313
[dependencies]
14-
async-std = { version = "1.12.0", optional = true }
1514
async-trait = { version = "0.1.56", optional = true }
1615
base64 = { version = "0.13.0", default-features = false }
1716
base64-simd = { version = "0.5.0", default-features = false, optional = true }
1817
byteorder = { version = "1.4.3", default-features = false }
1918
cfg-if = "1.0.0"
2019
core2 = "0.4.0"
21-
futures = { version = "0.3.21", optional = true }
2220
heapless = "0.7.14"
2321
httparse = { version = "1.7.1", default-features = false }
2422
rand_core = "0.6.3"
2523
sha1 = "0.10.1"
26-
smol = { version = "1.2.5", optional = true }
27-
tokio = { version = "1.19.2", features = ["io-util"], optional = true }
2824

2925
[dev-dependencies]
3026
async-std = { version = "1.12.0", features = ["attributes"] }
@@ -44,37 +40,36 @@ default = ["std"]
4440
# default = []
4541
std = []
4642
async = ["std", "async-trait"]
47-
tokio = ["dep:tokio", "async"]
48-
futures = ["dep:futures", "async"]
49-
smol = ["dep:smol", "async"]
50-
async-std = ["dep:async-std", "async"]
43+
example-tokio = ["async"]
44+
example-smol = ["async"]
45+
example-async-std = ["async"]
5146

5247
[[example]]
5348
name = "server_tokio"
5449
path = "examples/server_async/main.rs"
55-
required-features = ["tokio"]
50+
required-features = ["example-tokio"]
5651

5752
[[example]]
5853
name = "server_smol"
5954
path = "examples/server_async/main.rs"
60-
required-features = ["smol"]
55+
required-features = ["example-smol"]
6156

6257
[[example]]
6358
name = "server_async_std"
6459
path = "examples/server_async/main.rs"
65-
required-features = ["async-std"]
60+
required-features = ["example-async-std"]
6661

6762
[[example]]
6863
name = "client_tokio"
6964
path = "examples/client_async/main.rs"
70-
required-features = ["tokio"]
65+
required-features = ["example-tokio"]
7166

7267
[[example]]
7368
name = "client_smol"
7469
path = "examples/client_async/main.rs"
75-
required-features = ["smol"]
70+
required-features = ["example-smol"]
7671

7772
[[example]]
7873
name = "client_async_std"
7974
path = "examples/client_async/main.rs"
80-
required-features = ["async-std"]
75+
required-features = ["example-async-std"]

examples/client_async/compat.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#![allow(dead_code)]
2+
3+
// This is an example implementation of compatibility extension, gladly stolen from futures_lite
4+
// As this is far from being any useful, please do extend this on your own
5+
pub trait CompatExt {
6+
fn compat(self) -> Compat<Self>
7+
where
8+
Self: Sized;
9+
fn compat_ref(&self) -> Compat<&Self>;
10+
fn compat_mut(&mut self) -> Compat<&mut Self>;
11+
}
12+
13+
impl<T> CompatExt for T {
14+
fn compat(self) -> Compat<Self>
15+
where
16+
Self: Sized,
17+
{
18+
Compat(self)
19+
}
20+
21+
fn compat_ref(&self) -> Compat<&Self> {
22+
Compat(self)
23+
}
24+
25+
fn compat_mut(&mut self) -> Compat<&mut Self> {
26+
Compat(self)
27+
}
28+
}
29+
30+
pub struct Compat<T>(T);
31+
32+
impl<T> Compat<T> {
33+
pub fn get_ref(&self) -> &T {
34+
&self.0
35+
}
36+
37+
pub fn get_mut(&mut self) -> &mut T {
38+
&mut self.0
39+
}
40+
41+
pub fn into_inner(self) -> T {
42+
self.0
43+
}
44+
}
45+
46+
#[cfg(feature = "example-tokio")]
47+
pub mod tokio_compat {
48+
use super::Compat;
49+
use async_trait::async_trait;
50+
use embedded_websocket::compat::{AsyncRead, AsyncWrite};
51+
use tokio::io::{AsyncReadExt, AsyncWriteExt};
52+
53+
#[async_trait]
54+
impl<T: tokio::io::AsyncRead + Unpin + Send + Sync> AsyncRead<std::io::Error> for Compat<T> {
55+
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
56+
AsyncReadExt::read(self.get_mut(), buf).await
57+
}
58+
}
59+
60+
#[async_trait]
61+
impl<T: tokio::io::AsyncWrite + Unpin + Send + Sync> AsyncWrite<std::io::Error> for Compat<T> {
62+
async fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
63+
AsyncWriteExt::write_all(self.get_mut(), buf).await
64+
}
65+
}
66+
}
67+
68+
#[cfg(feature = "example-smol")]
69+
pub mod smol_compat {
70+
use super::Compat;
71+
use async_trait::async_trait;
72+
use embedded_websocket::compat::{AsyncRead, AsyncWrite};
73+
use smol::io::{AsyncReadExt, AsyncWriteExt};
74+
75+
#[async_trait]
76+
impl<T: smol::io::AsyncRead + Unpin + Send + Sync> AsyncRead<std::io::Error> for Compat<T> {
77+
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
78+
AsyncReadExt::read(self.get_mut(), buf).await
79+
}
80+
}
81+
82+
#[async_trait]
83+
impl<T: smol::io::AsyncWrite + Unpin + Send + Sync> AsyncWrite<std::io::Error> for Compat<T> {
84+
async fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
85+
AsyncWriteExt::write_all(self.get_mut(), buf).await
86+
}
87+
}
88+
}
89+
90+
#[cfg(feature = "example-async-std")]
91+
pub mod async_std_compat {
92+
use super::Compat;
93+
use async_std::io::{ReadExt, WriteExt};
94+
use async_trait::async_trait;
95+
use embedded_websocket::compat::{AsyncRead, AsyncWrite};
96+
97+
#[async_trait]
98+
impl<T: async_std::io::Read + Unpin + Send + Sync> AsyncRead<std::io::Error> for Compat<T> {
99+
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
100+
ReadExt::read(self.get_mut(), buf).await
101+
}
102+
}
103+
104+
#[async_trait]
105+
impl<T: async_std::io::Write + Unpin + Send + Sync> AsyncWrite<std::io::Error> for Compat<T> {
106+
async fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
107+
WriteExt::write_all(self.get_mut(), buf).await
108+
}
109+
}
110+
}

examples/client_async/main.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,28 @@
99
// Note that we are using the standard library in the demo and making use of the framer helper module
1010
// but the websocket library remains no_std (see client_full for an example without the framer helper module)
1111

12+
mod compat;
13+
14+
use crate::compat::CompatExt;
1215
use embedded_websocket::{
1316
framer::{Framer, FramerError, ReadResult},
1417
WebSocketClient, WebSocketCloseStatusCode, WebSocketOptions, WebSocketSendMessageType,
1518
};
1619
use std::error::Error;
1720

1821
cfg_if::cfg_if! {
19-
if #[cfg(feature = "tokio")] {
22+
if #[cfg(feature = "example-tokio")] {
2023
use tokio::net::TcpStream;
21-
} else if #[cfg(feature = "smol")] {
24+
} else if #[cfg(feature = "example-smol")] {
2225
use smol::net::TcpStream;
23-
} else if #[cfg(feature = "async-std")] {
26+
} else if #[cfg(feature = "example-async-std")] {
2427
use async_std::net::TcpStream;
2528
}
2629
}
2730

28-
#[cfg_attr(feature = "async-std", async_std::main)]
29-
#[cfg_attr(feature = "tokio", tokio::main)]
30-
#[cfg_attr(feature = "smol", smol_potat::main)]
31+
#[cfg_attr(feature = "example-async-std", async_std::main)]
32+
#[cfg_attr(feature = "example-tokio", tokio::main)]
33+
#[cfg_attr(feature = "example-smol", smol_potat::main)]
3134
async fn main() -> Result<(), FramerError<impl Error>> {
3235
// open a TCP stream to localhost port 1337
3336
let address = "127.0.0.1:1337";
@@ -56,6 +59,8 @@ async fn main() -> Result<(), FramerError<impl Error>> {
5659
&mut write_buf,
5760
&mut websocket,
5861
);
62+
let mut stream = stream.compat_mut();
63+
5964
framer
6065
.connect_async(&mut stream, &websocket_options)
6166
.await?;

examples/server_async/compat.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#![allow(dead_code)]
2+
3+
// This is an example implementation of compatibility extension, gladly stolen from futures_lite
4+
// As this is far from being any useful, please do extend this on your own
5+
pub trait CompatExt {
6+
fn compat(self) -> Compat<Self>
7+
where
8+
Self: Sized;
9+
fn compat_ref(&self) -> Compat<&Self>;
10+
fn compat_mut(&mut self) -> Compat<&mut Self>;
11+
}
12+
13+
impl<T> CompatExt for T {
14+
fn compat(self) -> Compat<Self>
15+
where
16+
Self: Sized,
17+
{
18+
Compat(self)
19+
}
20+
21+
fn compat_ref(&self) -> Compat<&Self> {
22+
Compat(self)
23+
}
24+
25+
fn compat_mut(&mut self) -> Compat<&mut Self> {
26+
Compat(self)
27+
}
28+
}
29+
30+
pub struct Compat<T>(T);
31+
32+
impl<T> Compat<T> {
33+
pub fn get_ref(&self) -> &T {
34+
&self.0
35+
}
36+
37+
pub fn get_mut(&mut self) -> &mut T {
38+
&mut self.0
39+
}
40+
41+
pub fn into_inner(self) -> T {
42+
self.0
43+
}
44+
}
45+
46+
#[cfg(feature = "example-tokio")]
47+
pub mod tokio_compat {
48+
use super::Compat;
49+
use async_trait::async_trait;
50+
use embedded_websocket::compat::{AsyncRead, AsyncWrite};
51+
use tokio::io::{AsyncReadExt, AsyncWriteExt};
52+
53+
#[async_trait]
54+
impl<T: tokio::io::AsyncRead + Unpin + Send + Sync> AsyncRead<std::io::Error> for Compat<T> {
55+
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
56+
AsyncReadExt::read(self.get_mut(), buf).await
57+
}
58+
}
59+
60+
#[async_trait]
61+
impl<T: tokio::io::AsyncWrite + Unpin + Send + Sync> AsyncWrite<std::io::Error> for Compat<T> {
62+
async fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
63+
AsyncWriteExt::write_all(self.get_mut(), buf).await
64+
}
65+
}
66+
}
67+
68+
#[cfg(feature = "example-smol")]
69+
pub mod smol_compat {
70+
use super::Compat;
71+
use async_trait::async_trait;
72+
use embedded_websocket::compat::{AsyncRead, AsyncWrite};
73+
use smol::io::{AsyncReadExt, AsyncWriteExt};
74+
75+
#[async_trait]
76+
impl<T: smol::io::AsyncRead + Unpin + Send + Sync> AsyncRead<std::io::Error> for Compat<T> {
77+
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
78+
AsyncReadExt::read(self.get_mut(), buf).await
79+
}
80+
}
81+
82+
#[async_trait]
83+
impl<T: smol::io::AsyncWrite + Unpin + Send + Sync> AsyncWrite<std::io::Error> for Compat<T> {
84+
async fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
85+
AsyncWriteExt::write_all(self.get_mut(), buf).await
86+
}
87+
}
88+
}
89+
90+
#[cfg(feature = "example-async-std")]
91+
pub mod async_std_compat {
92+
use super::Compat;
93+
use async_std::io::{ReadExt, WriteExt};
94+
use async_trait::async_trait;
95+
use embedded_websocket::compat::{AsyncRead, AsyncWrite};
96+
97+
#[async_trait]
98+
impl<T: async_std::io::Read + Unpin + Send + Sync> AsyncRead<std::io::Error> for Compat<T> {
99+
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, std::io::Error> {
100+
ReadExt::read(self.get_mut(), buf).await
101+
}
102+
}
103+
104+
#[async_trait]
105+
impl<T: async_std::io::Write + Unpin + Send + Sync> AsyncWrite<std::io::Error> for Compat<T> {
106+
async fn write_all(&mut self, buf: &[u8]) -> Result<(), std::io::Error> {
107+
WriteExt::write_all(self.get_mut(), buf).await
108+
}
109+
}
110+
}

0 commit comments

Comments
 (0)