-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
sync_bridge.rs
46 lines (41 loc) · 1.3 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
use pin_project_lite::pin_project;
use std::io::{Read, Write};
use std::pin::Pin;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
pin_project! {
/// Use a [`tokio::io::AsyncRead`] synchronously as a [`std::io::Read`] or
/// a [`tokio::io::AsyncWrite`] as a [`std::io::Write`].
#[derive(Debug)]
pub struct SyncIOBridge<T> {
src: Pin<Box<T>>,
#[pin]
rt: tokio::runtime::Handle,
}
}
impl<T: AsyncRead> Read for SyncIOBridge<T> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
let src = &mut self.src;
self.rt.block_on(src.read(buf))
}
}
impl<T: AsyncWrite> Write for SyncIOBridge<T> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let src = &mut self.src;
self.rt.block_on(src.write(buf))
}
fn flush(&mut self) -> std::io::Result<()> {
let src = &mut self.src;
self.rt.block_on(src.flush())
}
}
impl<T: AsyncRead> SyncIOBridge<T> {
/// Use a [`tokio::io::AsyncRead`] synchronously as a [`std::io::Read`] or
/// a [`tokio::io::AsyncWrite`] as a [`std::io::Write`].
///
/// This is useful with e.g. [`tokio::task::spawn_blocking`].
pub fn new(src: T) -> Self {
let src = Box::pin(src);
let rt = tokio::runtime::Handle::current();
Self { src, rt }
}
}