variable_len_reader/asynchronous/
writer.rs

1use core::future::Future;
2use core::pin::Pin;
3use core::task::{Context, Poll};
4use pin_project_lite::pin_project;
5use crate::asynchronous::AsyncVariableWritable;
6use crate::util::write_buf::*;
7
8pub trait WriterFuture<'a, W: ?Sized, B> {
9    fn new(writer: &'a mut W, buf: B) -> Self;
10    fn reset(self: Pin<&mut Self>, buf: B);
11}
12
13macro_rules! write_wrap_future {
14    (@$primitive: ty, $future: ident, $inner_future: ident, $bound: ident $(, $feature: meta)?) => {
15        $(
16        #[$feature]
17        )?
18        $crate::pin_project_lite::pin_project! {
19            $(
20            #[cfg_attr(docsrs, doc($feature))]
21            )?
22            #[derive(Debug)]
23            #[project(!Unpin)]
24            #[must_use = "futures do nothing unless you `.await` or poll them"]
25            pub struct $future<'a, W: ?Sized> {
26                #[pin]
27                inner: $inner_future<'a, W>,
28            }
29        }
30        $(
31        #[$feature]
32        )?
33        impl<'a, W: ?Sized> WriterFuture<'a, W, $primitive> for $future<'a, W> {
34            fn new(writer: &'a mut W, buf: $primitive) -> Self {
35                Self { inner: $inner_future::new(writer, Self::_handle(buf)) }
36            }
37            fn reset(self: Pin<&mut Self>, buf: $primitive) {
38                let me = self.project();
39                me.inner.reset(Self::_handle(buf));
40            }
41        }
42        $(
43        #[$feature]
44        )?
45        impl<'a, W: $bound + Unpin + ?Sized> Future for $future<'a, W> {
46            type Output = Result<(), W::Error>;
47
48            fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
49                self.project().inner.poll(cx)
50            }
51        }
52    };
53    (f $feature: meta, $primitive: ty, $future: ident, $inner_future: ident) => {
54        write_wrap_future!(@$primitive, $future, $inner_future, AsyncVariableWriter, $feature);
55    };
56    ($primitive: ty, $future: ident, $inner_future: ident able) => {
57        write_wrap_future!(@$primitive, $future, $inner_future, AsyncVariableWritable);
58    };
59}
60macro_rules! write_wrap_func {
61    (@$primitive: ty, $future: ident, $func: ident $(, $feature: meta)?) => {
62        $(
63        #[$feature]
64        #[cfg_attr(docsrs, doc($feature))]
65        )?
66        #[inline]
67        fn $func(&mut self, value: $primitive) -> $future<Self> where Self: Unpin {
68            $future::new(self, value)
69        }
70    };
71    (f $feature: meta, $primitive: ty, $future: ident, $func: ident) => {
72        write_wrap_func!(@$primitive, $future, $func, $feature);
73    };
74    ($primitive: ty, $future: ident, $func: ident) => {
75        write_wrap_func!(@$primitive, $future, $func);
76    };
77}
78
79/// AP means all-platform. This is used for usize/isize converting to u128/i128.
80/// CP means current-platform. It writes usize/isize directly.
81#[allow(unused_macros)]
82macro_rules! write_size_ap_future {
83    (f $feature: meta, $primitive: ty, $future: ident, $internal: ty, $inner_future: ident) => {
84        write_wrap_future!(f $feature, $primitive, $future, $inner_future);
85        #[$feature]
86        impl<'a, W: ?Sized> $future<'a, W> {
87            fn _handle(value: $primitive) -> $internal {
88                value as $internal
89            }
90        }
91    };
92}
93
94
95pin_project! {
96    #[derive(Debug)]
97    #[project(!Unpin)]
98    #[must_use = "futures do nothing unless you `.await` or poll them"]
99    pub struct WriteSingle<'a, W: ?Sized> {
100        #[pin]
101        writer: &'a mut W,
102        buf: Option<u8>,
103    }
104}
105impl<'a, W: ?Sized> WriterFuture<'a, W, u8> for WriteSingle<'a, W> {
106    fn new(writer: &'a mut W, buf: u8) -> Self {
107        Self { writer, buf: Some(buf) }
108    }
109    fn reset(self: Pin<&mut Self>, buf: u8) {
110        let me = self.project();
111        *me.buf = Some(buf);
112    }
113}
114impl<'a, W: AsyncVariableWritable + Unpin + ?Sized> Future for WriteSingle<'a, W> {
115    type Output = Result<(), W::Error>;
116
117    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
118        let mut me = self.project();
119        W::poll_write_single(Pin::new(&mut *me.writer), cx, me.buf)
120    }
121}
122
123pin_project! {
124    #[derive(Debug)]
125    #[project(!Unpin)]
126    #[must_use = "futures do nothing unless you `.await` or poll them"]
127    pub struct WriteMore<'a, W: ?Sized> {
128        #[pin]
129        writer: &'a mut W,
130        buf: WriteBuf<'a>,
131    }
132}
133impl<'a, W: ?Sized> WriterFuture<'a, W, WriteBuf<'a>> for WriteMore<'a, W> {
134    fn new(writer: &'a mut W, buf: WriteBuf<'a>) -> Self {
135        Self { writer, buf }
136    }
137    fn reset(self: Pin<&mut Self>, buf: WriteBuf<'a>) {
138        let me = self.project();
139        *me.buf = buf;
140    }
141}
142impl<'a, W: AsyncVariableWritable + Unpin + ?Sized> Future for WriteMore<'a, W> {
143    type Output = Result<(), W::Error>;
144
145    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
146        let mut me = self.project();
147        W::poll_write_more(Pin::new(&mut *me.writer), cx, me.buf)
148    }
149}
150
151#[cfg(feature = "bytes")]
152pin_project! {
153    #[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
154    #[derive(Debug)]
155    #[project(!Unpin)]
156    #[must_use = "futures do nothing unless you `.await` or poll them"]
157    pub struct WriteMoreBuf<'a, W: ?Sized, B> where B: bytes::Buf {
158        #[pin]
159        writer: &'a mut W,
160        #[pin]
161        buf: &'a mut B,
162    }
163}
164#[cfg(feature = "bytes")]
165impl<'a, W: AsyncVariableWritable + Unpin + ?Sized, B: bytes::Buf> Future for WriteMoreBuf<'a, W, B> {
166    type Output = Result<(), W::Error>;
167
168    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
169        let mut me = self.project();
170        W::poll_write_more_buf(Pin::new(&mut *me.writer), cx, &mut *me.buf)
171    }
172}
173
174
175write_wrap_future!(bool, WriteBool, WriteSingle able);
176impl<'a, W: ?Sized> WriteBool<'a, W> {
177    fn _handle(buf: bool) -> u8 {
178        if buf { 1 } else { 0 }
179    }
180}
181
182include!("write_bools.rs");
183
184include!("write_raw.rs");
185include!("write_raw_size.rs");
186
187include!("write_varint.rs");
188include!("write_varint_size.rs");
189include!("write_varint_long.rs");
190include!("write_varint_long_size.rs");
191
192include!("write_signed_varint.rs");
193include!("write_signed_varint_size.rs");
194include!("write_signed_varint_long.rs");
195include!("write_signed_varint_long_size.rs");
196
197include!("write_float_varint.rs");
198include!("write_float_varint_long.rs");
199
200#[cfg(feature = "async_u8_vec")]
201pin_project! {
202    #[cfg_attr(docsrs, doc(cfg(feature = "async_u8_vec")))]
203    #[derive(Debug)]
204    #[project(!Unpin)]
205    #[must_use = "futures do nothing unless you `.await` or poll them"]
206    pub struct WriteU8Vec<'a, W: ?Sized> {
207        #[pin]
208        inner: WriteUsizeVarintAp<'a, W>,
209        buf: Option<OwnedWriteBuf<alloc::vec::Vec<u8>>>,
210    }
211}
212#[cfg(feature = "async_u8_vec")]
213impl<'a, W: ?Sized> WriterFuture<'a, W, alloc::vec::Vec<u8>> for WriteU8Vec<'a, W> {
214    fn new(writer: &'a mut W, buf: alloc::vec::Vec<u8>) -> Self {
215        Self { inner: WriteUsizeVarintAp::new(writer, buf.len()), buf: Some(OwnedWriteBuf::new(buf)) }
216    }
217
218    fn reset(self: Pin<&mut Self>, buf: alloc::vec::Vec<u8>) {
219        let me = self.project();
220        me.inner.reset(buf.len());
221        *me.buf = Some(OwnedWriteBuf::new(buf));
222    }
223}
224#[cfg(feature = "async_u8_vec")]
225impl<'a, W: AsyncVariableWriter + Unpin + ?Sized> Future for WriteU8Vec<'a, W> {
226    type Output = Result<(), W::Error>;
227
228    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
229        let mut me = self.project();
230        let buf = match me.buf.as_mut() {
231            None => return Poll::Ready(Ok(())), Some(b) => b
232        };
233        core::task::ready!(me.inner.as_mut().poll(cx))?;
234        let mut ref_buf = buf.into();
235        let res = W::poll_write_more(Pin::new(&mut me.inner.project().inner.project().inner.project().writer), cx, &mut ref_buf);
236        let position = ref_buf.position();
237        buf.set_position(position);
238        core::task::ready!(res)?;
239        *me.buf = None;
240        Poll::Ready(Ok(()))
241    }
242}
243
244write_wrap_future!(f cfg(feature = "async_string"), alloc::string::String, WriteString, WriteU8Vec);
245#[cfg(feature = "async_string")]
246impl<'a, W: ?Sized> WriteString<'a, W> {
247    fn _handle(value: alloc::string::String) -> alloc::vec::Vec<u8> {
248        value.into_bytes()
249    }
250}
251
252pub trait AsyncVariableWriter: AsyncVariableWritable {
253    #[inline]
254    fn write_single(&mut self, byte: u8) -> WriteSingle<Self> where Self: Unpin {
255        WriteSingle::new(self, byte)
256    }
257
258    #[inline]
259    fn write_more<'a>(&'a mut self, buf: &'a [u8]) -> WriteMore<'a, Self> where Self: Unpin {
260        WriteMore { writer: self, buf: WriteBuf::new(buf) }
261    }
262
263    #[cfg(feature = "bytes")]
264    #[cfg_attr(docsrs, doc(cfg(feature = "bytes")))]
265    #[inline]
266    fn write_more_buf<'a, B: bytes::Buf>(&'a mut self, buf: &'a mut B) -> WriteMoreBuf<'a, Self, B> where Self: Unpin {
267        WriteMoreBuf { writer: self, buf }
268    }
269
270
271    write_wrap_func!(bool, WriteBool, write_bool);
272
273    define_write_bools_func!();
274
275    define_write_raw_func!();
276    define_write_raw_size_func!();
277
278    define_write_varint_func!();
279    define_write_varint_size_func!();
280    define_write_varint_long_func!();
281    define_write_varint_long_size_func!();
282
283    define_write_signed_varint_func!();
284    define_write_signed_varint_size_func!();
285    define_write_signed_varint_long_func!();
286    define_write_signed_varint_long_size_func!();
287
288    define_write_float_varint_func!();
289    define_write_float_long_func!();
290
291    #[allow(deprecated)]
292    /// This method consumes the vec.
293    ///
294    /// You can use the example instead.
295    /// ```rust,ignore
296    /// writer.write_usize_varint_ap(value.len()).await?;
297    /// writer.write_more(value).await?;
298    /// ```
299    /// Or you can simply call [Self::write_u8_vec_boxed] instead.
300    /// ```rust,ignore
301    /// writer.write_u8_vec_boxed(&value).await?;
302    /// ```
303    ///
304    /// Now you can call
305    /// ```rust,ignore
306    /// AsyncWriterHelper(&mut writer).help_write_u8_vec().await?;
307    /// ```
308    #[cfg(feature = "async_u8_vec")]
309    #[cfg_attr(docsrs, doc(cfg(feature = "async_u8_vec")))]
310    #[inline]
311    #[deprecated(since = "3.0.0", note = "see docs for details")]
312    fn write_u8_vec(&mut self, value: alloc::vec::Vec<u8>) -> WriteU8Vec<Self> where Self: Unpin {
313        WriteU8Vec::new(self, value)
314    }
315
316    #[allow(deprecated)]
317    /// This future is not zero-cost.
318    /// But it borrows the vec, different from [Self::write_u8_vec].
319    #[cfg(feature = "async_u8_vec")]
320    #[cfg_attr(docsrs, doc(cfg(feature = "async_u8_vec")))]
321    #[inline]
322    #[must_use = "futures do nothing unless you `.await` or poll them"]
323    #[deprecated(since = "3.2.0", note = "use [AsyncWriterHelper::help_write_u8_vec] instead")]
324    fn write_u8_vec_boxed<'a>(&'a mut self, value: &'a [u8]) -> Pin<alloc::boxed::Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'a>> where Self: Unpin + Send {
325        alloc::boxed::Box::pin(async move {
326            self.write_usize_varint_ap(value.len()).await?;
327            self.write_more(value).await?;
328            Ok(())
329        })
330    }
331
332    #[allow(deprecated)]
333    /// This method is based on [Self::write_u8_vec],
334    /// which consumes the value.
335    ///
336    /// Or you can simply call [Self::write_string_boxed] instead.
337    /// ```rust,ignore
338    /// writer.write_string_boxed().await?;
339    /// ```
340    ///
341    /// Now you can call
342    /// ```rust,ignore
343    /// AsyncWriterHelper(&mut writer).help_write_string().await?;
344    /// ```
345    #[cfg(feature = "async_string")]
346    #[cfg_attr(docsrs, doc(cfg(feature = "async_string")))]
347    #[inline]
348    #[deprecated(since = "3.0.0", note = "see docs for details")]
349    fn write_string(&mut self, value: alloc::string::String) -> WriteString<Self> where Self: Unpin {
350        WriteString::new(self, value)
351    }
352
353    #[allow(deprecated)]
354    /// This future is not zero-cost.
355    /// But it borrows the string, different from [Self::write_string].
356    #[cfg(feature = "async_string")]
357    #[cfg_attr(docsrs, doc(cfg(feature = "async_string")))]
358    #[inline]
359    #[must_use = "futures do nothing unless you `.await` or poll them"]
360    #[deprecated(since = "3.2.0", note = "use [AsyncWriterHelper::help_write_string] instead")]
361    fn write_string_boxed<'a>(&'a mut self, value: &'a str) -> Pin<alloc::boxed::Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'a>> where Self: Unpin + Send {
362        self.write_u8_vec_boxed(value.as_bytes())
363    }
364}