1use compio_buf::{
2 BufResult, IntoInner, IoBuf, IoBufExt, IoBufMut, IoBufMutExt, IoVectoredBuf, IoVectoredBufMut,
3 buf_try,
4};
5
6use crate::{
7 AsyncBufRead, AsyncRead, AsyncWrite, IoResult,
8 buffer::Buffer,
9 util::{DEFAULT_BUF_SIZE, slice_to_buf},
10};
11
12#[derive(Debug)]
35pub struct BufWriter<W> {
36 writer: W,
37 buf: Buffer,
38}
39
40impl<W> BufWriter<W> {
41 pub fn new(writer: W) -> Self {
44 Self::with_capacity(DEFAULT_BUF_SIZE, writer)
45 }
46
47 pub fn with_capacity(cap: usize, writer: W) -> Self {
49 Self {
50 writer,
51 buf: Buffer::with_capacity(cap),
52 }
53 }
54}
55
56impl<W: AsyncWrite> BufWriter<W> {
57 async fn flush_if_needed(&mut self) -> IoResult<()> {
58 if self.buf.need_flush() {
59 self.flush().await?;
60 }
61 Ok(())
62 }
63}
64
65impl<W: AsyncWrite> AsyncWrite for BufWriter<W> {
66 async fn write<T: IoBuf>(&mut self, mut buf: T) -> BufResult<usize, T> {
67 (_, buf) = buf_try!(self.flush_if_needed().await, buf);
70
71 let written = self
72 .buf
73 .with_sync(|w| {
74 let len = w.buf_len();
75 let mut w = w.slice(len..);
76 let written = slice_to_buf(buf.as_init(), &mut w);
77 BufResult(Ok(written), w.into_inner())
78 })
79 .expect("Closure always return Ok");
80
81 (_, buf) = buf_try!(self.flush_if_needed().await, buf);
82
83 BufResult(Ok(written), buf)
84 }
85
86 async fn write_vectored<T: IoVectoredBuf>(&mut self, mut buf: T) -> BufResult<usize, T> {
87 (_, buf) = buf_try!(self.flush_if_needed().await, buf);
88
89 let written = self
90 .buf
91 .with_sync(|mut w| {
92 let mut written = 0;
93 for buf in buf.iter_slice() {
94 let len = w.buf_len();
95 let mut slice = w.slice(len..);
96 written += slice_to_buf(buf, &mut slice);
97 w = slice.into_inner();
98
99 if w.buf_len() == w.buf_capacity() {
100 break;
101 }
102 }
103 BufResult(Ok(written), w)
104 })
105 .expect("Closure always return Ok");
106
107 (_, buf) = buf_try!(self.flush_if_needed().await, buf);
108
109 BufResult(Ok(written), buf)
110 }
111
112 async fn flush(&mut self) -> IoResult<()> {
113 let Self { writer, buf } = self;
114
115 buf.flush_to(writer).await?;
116
117 Ok(())
118 }
119
120 async fn shutdown(&mut self) -> IoResult<()> {
121 self.flush().await?;
122 self.writer.shutdown().await
123 }
124}
125
126impl<W: AsyncRead + AsyncWrite> AsyncRead for BufWriter<W> {
127 async fn read<B: IoBufMut>(&mut self, buf: B) -> BufResult<usize, B> {
128 self.writer.read(buf).await
129 }
130
131 async fn read_vectored<V: IoVectoredBufMut>(&mut self, buf: V) -> BufResult<usize, V> {
132 self.writer.read_vectored(buf).await
133 }
134}
135
136impl<W: AsyncBufRead + AsyncWrite> AsyncBufRead for BufWriter<W> {
137 async fn fill_buf(&mut self) -> IoResult<&'_ [u8]> {
138 self.writer.fill_buf().await
139 }
140
141 fn consume(&mut self, amount: usize) {
142 self.writer.consume(amount)
143 }
144}
145
146impl<W> IntoInner for BufWriter<W> {
147 type Inner = W;
148
149 fn into_inner(self) -> Self::Inner {
150 self.writer
151 }
152}