tokio_util/io/
sync_bridge.rs1use std::io::{BufRead, Read, Seek, Write};
2use tokio::io::{
3 AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite,
4 AsyncWriteExt,
5};
6
7#[derive(Debug)]
10pub struct SyncIoBridge<T> {
11 src: T,
12 rt: tokio::runtime::Handle,
13}
14
15impl<T: AsyncBufRead + Unpin> BufRead for SyncIoBridge<T> {
16 fn fill_buf(&mut self) -> std::io::Result<&[u8]> {
17 let src = &mut self.src;
18 self.rt.block_on(AsyncBufReadExt::fill_buf(src))
19 }
20
21 fn consume(&mut self, amt: usize) {
22 let src = &mut self.src;
23 AsyncBufReadExt::consume(src, amt)
24 }
25
26 fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> std::io::Result<usize> {
27 let src = &mut self.src;
28 self.rt
29 .block_on(AsyncBufReadExt::read_until(src, byte, buf))
30 }
31 fn read_line(&mut self, buf: &mut String) -> std::io::Result<usize> {
32 let src = &mut self.src;
33 self.rt.block_on(AsyncBufReadExt::read_line(src, buf))
34 }
35}
36
37impl<T: AsyncRead + Unpin> Read for SyncIoBridge<T> {
38 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
39 let src = &mut self.src;
40 self.rt.block_on(AsyncReadExt::read(src, buf))
41 }
42
43 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize> {
44 let src = &mut self.src;
45 self.rt.block_on(src.read_to_end(buf))
46 }
47
48 fn read_to_string(&mut self, buf: &mut String) -> std::io::Result<usize> {
49 let src = &mut self.src;
50 self.rt.block_on(src.read_to_string(buf))
51 }
52
53 fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
54 let src = &mut self.src;
55 let _n = self.rt.block_on(src.read_exact(buf))?;
57 Ok(())
58 }
59}
60
61impl<T: AsyncWrite + Unpin> Write for SyncIoBridge<T> {
62 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
63 let src = &mut self.src;
64 self.rt.block_on(src.write(buf))
65 }
66
67 fn flush(&mut self) -> std::io::Result<()> {
68 let src = &mut self.src;
69 self.rt.block_on(src.flush())
70 }
71
72 fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
73 let src = &mut self.src;
74 self.rt.block_on(src.write_all(buf))
75 }
76
77 fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result<usize> {
78 let src = &mut self.src;
79 self.rt.block_on(src.write_vectored(bufs))
80 }
81}
82
83impl<T: AsyncSeek + Unpin> Seek for SyncIoBridge<T> {
84 fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result<u64> {
85 let src = &mut self.src;
86 self.rt.block_on(AsyncSeekExt::seek(src, pos))
87 }
88}
89
90impl<T: AsyncWrite> SyncIoBridge<T> {
93 pub fn is_write_vectored(&self) -> bool {
97 self.src.is_write_vectored()
98 }
99}
100
101impl<T: AsyncWrite + Unpin> SyncIoBridge<T> {
102 pub fn shutdown(&mut self) -> std::io::Result<()> {
111 let src = &mut self.src;
112 self.rt.block_on(src.shutdown())
113 }
114}
115
116impl<T: Unpin> SyncIoBridge<T> {
117 #[track_caller]
139 pub fn new(src: T) -> Self {
140 Self::new_with_handle(src, tokio::runtime::Handle::current())
141 }
142
143 pub fn new_with_handle(src: T, rt: tokio::runtime::Handle) -> Self {
149 Self { src, rt }
150 }
151
152 pub fn into_inner(self) -> T {
154 self.src
155 }
156}