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#[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 #[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 #[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 #[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 #[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}