Skip to content

Commit 9395cfe

Browse files
authored
Merge pull request ohkami-rs#39 from ohkami-rs/reduce-runtime-crate-dependence
[BREAKING] reduce-runtime-crate-dependence
2 parents 1d340c5 + ecce126 commit 9395cfe

File tree

8 files changed

+85
-191
lines changed

8 files changed

+85
-191
lines changed

Cargo.toml

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,48 +13,30 @@ keywords = ["websocket", "io", "web", "async"]
1313
categories = ["web-programming::websocket", "network-programming", "asynchronous"]
1414

1515
[package.metadata.docs.rs]
16-
features = ["rt_tokio"]
16+
features = ["io_tokio"]
1717

1818
[dependencies]
19-
tokio = { optional = true, version = "1" }
20-
smol = { optional = true, version = "2" }
21-
glommio = { optional = true, version = "0.9" }
22-
nio = { optional = true, version = "0.0" }
23-
24-
futures-util = { version = "0.3", default-features = false }
19+
# IO interfaces / utilities
20+
tokio = { optional = true, version = "1" }
21+
futures-util = { optional = true, version = "0.3", default-features = false }
2522

23+
# crypto / encoding
2624
sha1 = { version = "0.10", default-features = false }
2725
base64 = { version = "0.22" }
2826

2927
[features]
30-
### runtimes ###
31-
rt_tokio = [
32-
"__runtime__", "__io_tokio__",
33-
"dep:tokio","tokio/net","tokio/sync","tokio/time",
34-
]
35-
rt_smol = [
36-
"__runtime__", "__io_futures__",
37-
"dep:smol"
38-
]
39-
rt_glommio = [
40-
"__runtime__", "__io_futures__",
41-
"dep:glommio"
28+
io_tokio = ["__io__",
29+
"dep:tokio","tokio/io-util",
30+
"dep:futures-util","futures-util/alloc","futures-util/unstable","futures-util/bilock" # for `BiLock` for `split` impl
4231
]
43-
rt_nio = [
44-
"__runtime__", "__io_tokio__",
45-
"dep:nio",
46-
"dep:tokio","tokio/sync"
32+
io_futures = ["__io__",
33+
"dep:futures-util", "futures-util/io"
4734
]
4835

49-
### optimizations ###
50-
tcpstream-only = []
51-
5236
### internal ###
53-
__runtime__ = []
54-
__io_tokio__ = ["dep:tokio","tokio/io-util", "futures-util/alloc","futures-util/unstable","futures-util/bilock"]
55-
__io_futures__ = ["futures-util/io"]
37+
__io__ = [
38+
"dep:tokio","tokio/sync" # for `RwLock` for `Connection`'s close handling
39+
]
5640

57-
#####################################
58-
DEBUG = ["tokio?/rt"] ###############
59-
## default = ["rt_tokio", "DEBUG"] ##
60-
#####################################
41+
[dev-dependencies]
42+
tokio = { version = "1", features = ["full"] }

README.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515

1616
* Minimal and Efficient : minimal codebase to provide efficient, memory-safe WebSocket handling.
1717

18-
* Multi-Environment : `tokio`, `smol`, `glommio`, `nio` are supported as async runtime ( by feature flags `rt_{name}` ).
18+
* Multi-Environment : works with any async runtimes with `tokio::io` or `futures_io` interface
19+
(for example: `tokio` or `nio` use `tokio::io` interface,
20+
and `smol` or `glommio` use `futures_io` interface).\
21+
Feature flags **`io_tokio`** or **`io_futures`** enables integration for respective IO interface.
1922

2023
## Note
2124

@@ -25,15 +28,15 @@ MEWS is NOT WebSocket server, just protocol implementation. So :
2528

2629
* Doesn't builtins `wss://` support.
2730

28-
## Feature Flags
31+
## Usage
2932

30-
- `tcpstream-only` : limit `split` functionality to only the runtime's `TcpStream`, in exchange for possible performance optimization.
33+
**`io_tokio`** or **`io_futures`** must be activated to integrate with async IO interfaces.
3134

32-
## Example
35+
Here specifying `io_tokio` to use with `tokio`:
3336

3437
```toml
3538
[dependencies]
36-
mews = { version = "0.4.0", features = ["rt_tokio"] }
39+
mews = { version = "0.4.0", features = ["io_tokio"] }
3740
tokio = { version = "1", features = ["full"] }
3841
# ...
3942
```

Taskfile.yaml

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,20 @@ version: 3
33
tasks:
44
CI:
55
deps:
6-
- for: [tokio, smol, glommio, nio]
7-
task: test:rt
8-
vars: { rt: '{{.ITEM}}' }
9-
- task: test:no_rt
6+
- for: [tokio, futures]
7+
task: test:with_io
8+
vars: { io: '{{.ITEM}}' }
9+
- task: test:without_io
1010
- task: test:doc
1111

12-
test:rt:
12+
test:with_io:
1313
cmds:
14-
- cargo test --lib --features rt_{{.rt}}
15-
- cargo test --lib --features rt_{{.rt}},tcpstream-only
14+
- cargo test --lib --features io_{{.io}}
1615

17-
test:no_rt:
16+
test:without_io:
1817
cmds:
1918
- cargo test
2019

2120
test:doc:
2221
cmds:
23-
- cargo test --doc --features rt_tokio,DEBUG
22+
- cargo test --doc --features io_tokio

src/connection.rs

Lines changed: 7 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
#![cfg(feature="__io__")]
2+
3+
use crate::io::{AsyncRead, AsyncWrite};
4+
use crate::sync::RwLock;
15
use crate::{Config, Message};
2-
use crate::runtime::{AsyncRead, AsyncWrite, RwLock};
36
use std::{sync::Arc, io::Error};
47

58
pub trait UnderlyingConnection: AsyncRead + AsyncWrite + Unpin + 'static {}
@@ -19,24 +22,11 @@ pub struct Connection<C: UnderlyingConnection> {
1922
/*============================================================*/
2023
#[inline(always)]
2124
async fn read_closed(__closed__: &RwLock<bool>) -> bool {
22-
#[cfg(feature="rt_glommio")]
23-
match __closed__.read().await {
24-
Ok(read) => *read,
25-
Err(_/* closed */) => true
26-
}
27-
#[cfg(not(feature="rt_glommio"))]
2825
*__closed__.read().await
2926
}
3027
#[inline(always)]
3128
async fn set_closed(__closed__: &RwLock<bool>) {
32-
#[cfg(feature="rt_glommio")] {
33-
if let Ok(mut write) = __closed__.write().await {
34-
*write = true
35-
}
36-
}
37-
#[cfg(not(feature="rt_glommio"))] {
38-
*__closed__.write().await = true
39-
}
29+
*__closed__.write().await = true
4030
}
4131

4232
const ALREADY_CLOSED_MESSAGE: &str = "\n\
@@ -333,17 +323,8 @@ pub mod split {
333323
}
334324
}
335325

336-
#[cfg(feature="__io_futures__")]
326+
#[cfg(feature="io_futures")]
337327
const _: (/* futures-io users */) = {
338-
#[cfg(feature="tcpstream-only")]
339-
impl<'split> Splitable<'split> for crate::runtime::net::TcpStream {
340-
type ReadHalf = futures_util::io::ReadHalf<&'split mut Self>;
341-
type WriteHalf = futures_util::io::WriteHalf<&'split mut Self>;
342-
fn split(&'split mut self) -> (Self::ReadHalf, Self::WriteHalf) {
343-
AsyncRead::split(self)
344-
}
345-
}
346-
#[cfg(not(feature="tcpstream-only"))]
347328
impl<'split, T: AsyncRead + AsyncWrite + Unpin + 'split> Splitable<'split> for T {
348329
type ReadHalf = futures_util::io::ReadHalf<&'split mut T>;
349330
type WriteHalf = futures_util::io::WriteHalf<&'split mut T>;
@@ -353,20 +334,7 @@ pub mod split {
353334
}
354335
};
355336

356-
#[cfg(feature="__io_tokio__")]
357-
#[cfg(feature="tcpstream-only")]
358-
const _: (/* tokio::io users */) = {
359-
/* efficient-able specialized impl for `TcpStream` */
360-
impl<'split> Splitable<'split> for crate::runtime::net::TcpStream {
361-
type ReadHalf = crate::runtime::net::tcp::ReadHalf<'split>;
362-
type WriteHalf = crate::runtime::net::tcp::WriteHalf<'split>;
363-
fn split(&'split mut self) -> (Self::ReadHalf, Self::WriteHalf) {
364-
crate::runtime::net::TcpStream::split(self)
365-
}
366-
}
367-
};
368-
#[cfg(feature="__io_tokio__")]
369-
#[cfg(not(feature="tcpstream-only"))]
337+
#[cfg(feature="io_tokio")]
370338
const _: (/* tokio::io users */) = {
371339
impl<'split, T: AsyncRead + AsyncWrite + Unpin + 'split> Splitable<'split> for T {
372340
type ReadHalf = TokioIoReadHalf<'split, T>;
@@ -494,15 +462,3 @@ pub mod split {
494462
}
495463
}
496464
}
497-
498-
#[cfg(test)]
499-
mod tests {
500-
use super::*;
501-
502-
#[cfg(feature="__runtime__")]
503-
#[test]
504-
fn test_impl_splitable() {
505-
fn assert_impl_splitable<T: split::Splitable<'static>>() {}
506-
assert_impl_splitable::<crate::runtime::net::TcpStream>();
507-
}
508-
}

src/frame.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
#![cfg(feature="__io__")]
2+
13
use std::io::{Error, ErrorKind};
2-
use crate::runtime::{AsyncRead, AsyncWrite};
4+
use crate::io::{AsyncRead, AsyncWrite};
35
use crate::Config;
46

5-
67
#[derive(Debug, PartialEq)]
78
pub(crate) enum OpCode {
89
/* data op codes */
@@ -45,7 +46,7 @@ pub(crate) struct Frame {
4546
pub(crate) payload: Vec<u8>,
4647
}
4748

48-
#[cfg(feature="__runtime__")]
49+
#[cfg(feature="__io__")]
4950
impl Frame {
5051
pub(crate) async fn read_from(
5152
stream: &mut (impl AsyncRead + Unpin),

src/lib.rs

Lines changed: 17 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -25,72 +25,31 @@
2525
//!
2626
//! * Doesn't builtins `wss://` support.
2727
28-
#[cfg(any(
29-
all(feature="rt_tokio", any(feature="rt_smol", feature="rt_glommio")),
30-
all(feature="rt_smol", any(feature="rt_glommio", feature="rt_tokio" )),
31-
all(feature="rt_glommio", any(feature="rt_tokio", feature="rt_smol" )),
32-
))]
33-
compile_error! {"More than one runtime feature flags can't be activated"}
34-
35-
#[cfg(feature="rt_tokio")]
36-
mod runtime {
37-
pub use {
38-
tokio::io::AsyncReadExt as AsyncRead,
39-
tokio::io::AsyncWriteExt as AsyncWrite,
40-
tokio::sync::RwLock,
41-
tokio::time::sleep
42-
};
43-
#[cfg(any(test, feature="tcpstream-only"))]
44-
pub use tokio::net;
45-
}
46-
#[cfg(feature="rt_smol")]
47-
mod runtime {
48-
pub use {
49-
futures_util::AsyncReadExt as AsyncRead,
50-
futures_util::AsyncWriteExt as AsyncWrite,
51-
smol::lock::RwLock,
52-
};
53-
pub async fn sleep(duration: std::time::Duration) {
54-
smol::Timer::after(duration).await;
55-
}
56-
#[cfg(any(test, feature="tcpstream-only"))]
57-
pub use smol::net;
28+
#[cfg(feature="__io__")]
29+
mod io {
30+
#[cfg(feature="io_tokio")]
31+
pub(crate) use tokio::io::{AsyncReadExt as AsyncRead, AsyncWriteExt as AsyncWrite};
32+
#[cfg(feature="io_futures")]
33+
pub(crate) use futures_util::io::{AsyncReadExt as AsyncRead, AsyncWriteExt as AsyncWrite};
5834
}
59-
#[cfg(feature="rt_glommio")]
60-
mod runtime {
61-
pub use {
62-
futures_util::AsyncReadExt as AsyncRead,
63-
futures_util::AsyncWriteExt as AsyncWrite,
64-
glommio::sync::RwLock,
65-
glommio::timer::sleep
66-
};
67-
#[cfg(any(test, feature="tcpstream-only"))]
68-
pub use glommio::net;
69-
}
70-
#[cfg(feature="rt_nio")]
71-
mod runtime {
72-
pub use {
73-
tokio::io::AsyncReadExt as AsyncRead,
74-
tokio::io::AsyncWriteExt as AsyncWrite,
75-
tokio::sync::RwLock,
76-
nio::time::sleep
77-
};
78-
#[cfg(any(test, feature="tcpstream-only"))]
79-
pub use nio::net;
35+
36+
#[cfg(feature="__io__")]
37+
mod sync {
38+
pub(crate) use tokio::sync::RwLock;
8039
}
8140

41+
#[cfg(feature="__io__")]
8242
pub mod message;
83-
#[cfg(feature="__runtime__")]
43+
#[cfg(feature="__io__")]
8444
pub mod frame;
85-
#[cfg(feature="__runtime__")]
45+
#[cfg(feature="__io__")]
8646
pub mod websocket;
87-
#[cfg(feature="__runtime__")]
47+
#[cfg(feature="__io__")]
8848
pub mod connection;
8949

90-
pub use message::{Message, CloseFrame, CloseCode};
91-
#[cfg(feature="__runtime__")]
50+
#[cfg(feature="__io__")]
9251
pub use {
52+
message::{Message, CloseFrame, CloseCode},
9353
websocket::*,
94-
connection::Connection,
95-
connection::split::{self, Splitable, ReadHalf, WriteHalf},
54+
connection::{Connection, split::{self, Splitable, ReadHalf, WriteHalf}},
9655
};

src/message.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
#[cfg(feature="__runtime__")]
2-
use {
3-
std::io::{Error, ErrorKind},
4-
crate::runtime::{AsyncRead, AsyncWrite},
5-
crate::frame::{Frame, OpCode},
6-
crate::Config,
7-
};
1+
#![cfg(feature="__io__")]
2+
use crate::frame::{Frame, OpCode};
3+
use crate::io::{AsyncRead, AsyncWrite};
4+
use crate::Config;
5+
use std::io::{Error, ErrorKind};
86

97
#[derive(Debug)]
108
pub enum Message {
@@ -85,7 +83,7 @@ impl CloseCode {
8583
}
8684
}
8785

88-
#[cfg(feature="__runtime__")]
86+
#[cfg(feature="__io__")]
8987
impl CloseCode {
9088
pub(super) fn from_bytes(bytes: [u8; 2]) -> Self {
9189
Self::from(u16::from_be_bytes(bytes))
@@ -97,7 +95,7 @@ impl CloseCode {
9795
}
9896
}
9997

100-
#[cfg(feature="__runtime__")]
98+
#[cfg(feature="__io__")]
10199
impl Message {
102100
const PING_PONG_PAYLOAD_LIMIT: usize = 125;
103101

0 commit comments

Comments
 (0)