Skip to content

Commit 9c3c5b9

Browse files
committed
feat(io): add general split method
1 parent a26dbe5 commit 9c3c5b9

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

compio-io/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ repository = { workspace = true }
1212

1313
[dependencies]
1414
compio-buf = { workspace = true, features = ["arrayvec"] }
15+
futures-util = { workspace = true }
1516
paste = { workspace = true }
1617

1718
[dev-dependencies]

compio-io/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,13 @@ mod buffer;
107107
#[cfg(feature = "compat")]
108108
pub mod compat;
109109
mod read;
110+
mod split;
110111
pub mod util;
111112
mod write;
112113

113114
pub(crate) type IoResult<T> = std::io::Result<T>;
114115

115116
pub use read::*;
117+
pub use split::*;
116118
pub use util::{copy, null, repeat};
117119
pub use write::*;

compio-io/src/split.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use std::sync::Arc;
2+
3+
use compio_buf::{BufResult, IoBuf, IoBufMut, IoVectoredBuf, IoVectoredBufMut};
4+
use futures_util::lock::Mutex;
5+
6+
use crate::{AsyncRead, AsyncWrite, IoResult};
7+
8+
/// Splits a single value implementing `AsyncRead + AsyncWrite` into separate
9+
/// [`AsyncRead`] and [`AsyncWrite`] handles.
10+
pub fn split<T: AsyncRead + AsyncWrite>(stream: T) -> (ReadHalf<T>, WriteHalf<T>) {
11+
let stream = Arc::new(Mutex::new(stream));
12+
(ReadHalf(stream.clone()), WriteHalf(stream))
13+
}
14+
15+
/// The readable half of a value returned from [`split`].
16+
pub struct ReadHalf<T>(Arc<Mutex<T>>);
17+
18+
impl<T: AsyncRead> AsyncRead for ReadHalf<T> {
19+
async fn read<B: IoBufMut>(&mut self, buf: B) -> BufResult<usize, B> {
20+
self.0.lock().await.read(buf).await
21+
}
22+
23+
async fn read_vectored<V: IoVectoredBufMut>(&mut self, buf: V) -> BufResult<usize, V> {
24+
self.0.lock().await.read_vectored(buf).await
25+
}
26+
}
27+
28+
/// The writable half of a value returned from [`split`].
29+
pub struct WriteHalf<T>(Arc<Mutex<T>>);
30+
31+
impl<T: AsyncWrite> AsyncWrite for WriteHalf<T> {
32+
async fn write<B: IoBuf>(&mut self, buf: B) -> BufResult<usize, B> {
33+
self.0.lock().await.write(buf).await
34+
}
35+
36+
async fn write_vectored<B: IoVectoredBuf>(&mut self, buf: B) -> BufResult<usize, B> {
37+
self.0.lock().await.write_vectored(buf).await
38+
}
39+
40+
async fn flush(&mut self) -> IoResult<()> {
41+
self.0.lock().await.flush().await
42+
}
43+
44+
async fn shutdown(&mut self) -> IoResult<()> {
45+
self.0.lock().await.shutdown().await
46+
}
47+
}

0 commit comments

Comments
 (0)