-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
sync_bridge.rs
58 lines (51 loc) · 1.71 KB
/
sync_bridge.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use std::io::{Read, Write};
use std::pin::Pin;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
/// A [`std::io::Read`] implementation backed by an asynchronous source.
#[derive(Debug)]
pub struct ReadBridge<T> {
reader: Pin<Box<T>>,
rt: tokio::runtime::Handle,
}
impl<T: AsyncRead> Read for ReadBridge<T> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let reader = &mut self.reader;
self.rt.block_on(async { reader.read(buf).await })
}
}
impl<T: AsyncRead> ReadBridge<T> {
/// Create a [`std::io::Read`] implementation backed by an asynchronous source.
///
/// This is useful with e.g. [`tokio::task::spawn_blocking`].
pub fn new(reader: T) -> Self {
let reader = Box::pin(reader);
let rt = tokio::runtime::Handle::current();
ReadBridge { reader, rt }
}
}
/// A [`std::io::Write`] implementation backed by an asynchronous source.
#[derive(Debug)]
pub struct WriteBridge<T> {
w: Pin<Box<T>>,
rt: tokio::runtime::Handle,
}
impl<T: AsyncWrite> Write for WriteBridge<T> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let w = &mut self.w;
self.rt.block_on(async { w.write(buf).await })
}
fn flush(&mut self) -> std::io::Result<()> {
let w = &mut self.w;
self.rt.block_on(async { w.flush().await })
}
}
impl<T: AsyncWrite> WriteBridge<T> {
/// Create a [`std::io::Write`] implementation backed by an asynchronous source.
///
/// This is useful with e.g. [`tokio::task::spawn_blocking`].
pub fn new(reader: T) -> Self {
let w = Box::pin(reader);
let rt = tokio::runtime::Handle::current();
WriteBridge { w, rt }
}
}