1use std::collections::VecDeque;
4
5use bytes::{BufMut as _, Bytes, BytesMut};
6use futures::{Stream, StreamExt as _};
7use tokio::io::{AsyncRead, AsyncReadExt as _};
8use tokio::sync::mpsc;
9use tokio_util::codec::{Decoder, Encoder};
10
11use crate::{Decode, Deferred as _, DeferredFn, Encode, Index, Sink, encode_ready_bytes_header};
12
13#[derive(Clone)]
15pub struct Packer(mpsc::UnboundedSender<(usize, VecDeque<Bytes>)>);
16
17impl Packer {
18 fn push(&self, offset: usize, bufs: VecDeque<Bytes>) -> std::io::Result<()> {
19 self.0
20 .send((offset, bufs))
21 .map_err(|_| std::io::Error::from(std::io::ErrorKind::BrokenPipe))
22 }
23
24 fn push_bytes(&self, offset: usize, mut chunks: VecDeque<Bytes>) -> std::io::Result<()> {
25 let mut header = BytesMut::default();
26 encode_ready_bytes_header(chunks.iter().map(Bytes::len).sum(), &mut header)?;
27 chunks.push_front(header.freeze());
28 self.push(offset, chunks)
29 }
30}
31
32impl Index for Packer {
33 fn index(&self, _: &[usize]) -> std::io::Result<Self> {
34 Ok(self.clone())
35 }
36}
37
38impl Sink for Packer {
39 async fn write_future<T>(
40 self,
41 offset: usize,
42 item: impl Future<Output = T> + Send + 'static,
43 ) -> std::io::Result<()>
44 where
45 T: Encode<Self>,
46 std::io::Error: From<<T::Encoder as Encoder<T>>::Error>,
47 {
48 let mut buf = BytesMut::default();
49 buf.put_u8(0x01);
50 let deferred = T::encode(item.await, &mut T::Encoder::default(), &mut buf)?;
51 fill(deferred, &mut buf).await?;
52 self.push(offset, VecDeque::from([buf.freeze()]))
53 }
54
55 async fn write_stream<T>(
56 self,
57 offset: usize,
58 items: impl Stream<Item = Vec<T>> + Send + Unpin + 'static,
59 ) -> std::io::Result<()>
60 where
61 T: Encode<Self> + Send + 'static,
62 std::io::Error: From<<T::Encoder as Encoder<T>>::Error>,
63 {
64 self.write_future(offset, items.concat()).await
65 }
66
67 async fn write_stream_bytes(
68 self,
69 offset: usize,
70 items: impl Stream<Item = Bytes> + Send + Unpin + 'static,
71 ) -> std::io::Result<()> {
72 self.push_bytes(offset, items.collect().await)
73 }
74
75 async fn write_stream_read(
76 self,
77 offset: usize,
78 mut ready: BytesMut,
79 mut items: impl AsyncRead + Send + Unpin + 'static,
80 ) -> std::io::Result<()> {
81 while items.read_buf(&mut ready).await? > 0 {}
82 self.push_bytes(offset, VecDeque::from([ready.freeze()]))
83 }
84}
85
86async fn fill(deferred: Option<DeferredFn<Packer>>, dst: &mut BytesMut) -> std::io::Result<()> {
87 let Some(f) = deferred else {
88 return Ok(());
89 };
90 let (tx, mut rx) = mpsc::unbounded_channel();
91 f(Packer(tx), Vec::default()).await?;
92 let mut holes = Vec::default();
93 while let Some(hole) = rx.recv().await {
94 holes.push(hole);
95 }
96 holes.sort_unstable_by_key(|(offset, _)| *offset);
97 let n = holes
98 .iter()
99 .flat_map(|(_, bufs)| bufs)
100 .map(Bytes::len)
101 .sum::<usize>();
102 let mut out = BytesMut::with_capacity(dst.len() + n);
103 let mut prev = 0;
104 for (offset, bufs) in holes {
105 if offset < prev || dst.get(offset) != Some(&0x00) {
106 return Err(std::io::Error::new(
107 std::io::ErrorKind::InvalidData,
108 "asynchronous value was not encoded at the expected offset",
109 ));
110 }
111 out.extend_from_slice(&dst[prev..offset]);
112 for buf in bufs {
113 out.extend_from_slice(&buf);
114 }
115 prev = offset + 1;
116 }
117 out.extend_from_slice(&dst[prev..]);
118 *dst = out;
119 Ok(())
120}
121
122pub async fn pack<T: Encode<Packer>>(
138 v: T,
139 dst: &mut BytesMut,
140) -> Result<(), <T::Encoder as Encoder<T>>::Error> {
141 let deferred = v.encode(&mut T::Encoder::default(), dst)?;
142 fill(deferred, dst).await?;
143 Ok(())
144}
145
146pub fn pack_ready<T: Encode<Packer>>(
157 v: T,
158 dst: &mut BytesMut,
159) -> Result<(), <T::Encoder as Encoder<T>>::Error> {
160 let deferred = v.encode(&mut T::Encoder::default(), dst)?;
161 if deferred.is_some() {
162 return Err(std::io::Error::new(
163 std::io::ErrorKind::WouldBlock,
164 "asynchronous value is pending",
165 )
166 .into());
167 }
168 Ok(())
169}
170
171pub fn unpack<T: Decode>(buf: &mut BytesMut) -> Result<T, <T::Decoder as Decoder>::Error> {
178 let mut dec = T::Decoder::default();
179 let Some(v) = dec.decode(buf)? else {
180 return Err(
181 std::io::Error::new(std::io::ErrorKind::UnexpectedEof, "buffer is incomplete").into(),
182 );
183 };
184 if dec.take_deferred().is_some() {
185 return Err(std::io::Error::new(
186 std::io::ErrorKind::InvalidData,
187 "buffer contains pending asynchronous values, which cannot be unpacked",
188 )
189 .into());
190 }
191 if !buf.is_empty() {
192 return Err(std::io::Error::new(
193 std::io::ErrorKind::InvalidData,
194 "buffer contains trailing bytes",
195 )
196 .into());
197 }
198 Ok(v)
199}
200
201#[cfg(test)]
202mod tests {
203 use core::future::{pending, ready};
204 use core::pin::Pin;
205 use core::time::Duration;
206
207 use futures::FutureExt as _;
208 use futures::stream::{self, BoxStream};
209 use tokio::sync::oneshot;
210 use tokio::task::yield_now;
211 use tokio_util::io::StreamReader;
212
213 use super::*;
214
215 #[test_log::test(tokio::test)]
216 async fn sync() -> anyhow::Result<()> {
217 let mut buf = BytesMut::default();
218 pack((0x42_u8, "foo".to_string()), &mut buf).await?;
219 assert_eq!(buf.as_ref(), b"\x42\x03foo");
220 let (a, b) = unpack::<(u8, String)>(&mut buf)?;
221 assert_eq!(a, 0x42);
222 assert_eq!(b, "foo");
223 Ok(())
224 }
225
226 #[test_log::test(tokio::test)]
227 async fn future() -> anyhow::Result<()> {
228 let (tx, rx) = oneshot::channel::<u32>();
229 let fut: Pin<Box<dyn Future<Output = Pin<Box<dyn Future<Output = u32> + Send>>> + Send>> =
230 Box::pin(ready(
231 Box::pin(async { rx.await.unwrap() }) as Pin<Box<dyn Future<Output = u32> + Send>>
232 ));
233 let mut buf = BytesMut::default();
234 let (res, ()) = tokio::join!(pack((fut, 0x01_u8), &mut buf), async {
235 tx.send(0x42).unwrap();
236 });
237 res?;
238 assert_eq!(buf.as_ref(), b"\x01\x01\x42\x01");
239
240 let (fut, v) = unpack::<(
241 Pin<Box<dyn Future<Output = Pin<Box<dyn Future<Output = u32> + Send>>> + Send>>,
242 u8,
243 )>(&mut buf)?;
244 assert_eq!(v, 0x01);
245 assert_eq!(fut.await.await, 0x42);
246 Ok(())
247 }
248
249 #[test_log::test(tokio::test)]
250 async fn stream() -> anyhow::Result<()> {
251 let s: Pin<Box<dyn Stream<Item = Vec<Pin<Box<dyn Future<Output = u8> + Send>>>> + Send>> =
252 Box::pin(stream::iter([
253 vec![
254 Box::pin(async { 1_u8 }) as Pin<Box<dyn Future<Output = u8> + Send>>,
255 Box::pin(async { 2 }),
256 ],
257 vec![],
258 vec![Box::pin(async { 3 })],
259 ]));
260 let mut buf = BytesMut::default();
261 pack(s, &mut buf).await?;
262 assert_eq!(buf.as_ref(), b"\x01\x03\x01\x01\x01\x02\x01\x03");
263
264 let s = unpack::<
265 Pin<Box<dyn Stream<Item = Vec<Pin<Box<dyn Future<Output = u8> + Send>>>> + Send>>,
266 >(&mut buf)?;
267 let mut vs = vec![];
268 for fut in s.concat().await {
269 vs.push(fut.await);
270 }
271 assert_eq!(vs, [1, 2, 3]);
272 Ok(())
273 }
274
275 #[test_log::test(tokio::test)]
276 async fn stream_bytes() -> anyhow::Result<()> {
277 let s: Pin<Box<dyn Stream<Item = Bytes> + Send>> = Box::pin(stream::iter([
278 Bytes::from_static(b"foo"),
279 Bytes::from_static(b"bar"),
280 ]));
281 let r: Pin<Box<dyn AsyncRead + Send>> = Box::pin(std::io::Cursor::new(b"baz"));
282 let mut buf = BytesMut::default();
283 pack((s, r), &mut buf).await?;
284 assert_eq!(buf.as_ref(), b"\x01\x06foobar\x01\x03baz");
285
286 let (s, mut r) = unpack::<(
287 Pin<Box<dyn Stream<Item = Bytes> + Send>>,
288 Pin<Box<dyn AsyncRead + Send>>,
289 )>(&mut buf)?;
290 let s: Vec<Bytes> = s.collect().await;
291 assert_eq!(s.concat(), b"foobar");
292 let mut v = vec![];
293 r.read_to_end(&mut v).await?;
294 assert_eq!(v, b"baz");
295 Ok(())
296 }
297
298 #[test_log::test(tokio::test)]
299 async fn stream_empty() -> anyhow::Result<()> {
300 let s: Pin<Box<dyn Stream<Item = Vec<u8>> + Send>> = Box::pin(stream::empty());
301 let b: Pin<Box<dyn Stream<Item = Bytes> + Send>> = Box::pin(stream::empty());
302 let mut buf = BytesMut::default();
303 pack((s, b, tokio::io::empty()), &mut buf).await?;
304 assert_eq!(buf.as_ref(), b"\x01\x00\x01\x00\x01\x00");
305
306 let (s, b, mut r) = unpack::<(
307 Pin<Box<dyn Stream<Item = Vec<u8>> + Send>>,
308 Pin<Box<dyn Stream<Item = Bytes> + Send>>,
309 Pin<Box<dyn AsyncRead + Send>>,
310 )>(&mut buf)?;
311 assert!(s.concat().await.is_empty());
312 assert_eq!(b.count().await, 0);
313 let mut v = vec![];
314 r.read_to_end(&mut v).await?;
315 assert!(v.is_empty());
316 Ok(())
317 }
318
319 fn ready_then_pending<T: Send + 'static>(ready: T, pending: T) -> BoxStream<'static, T> {
320 stream::iter([ready])
321 .chain(stream::once(async {
322 yield_now().await;
323 pending
324 }))
325 .boxed()
326 }
327
328 #[test_log::test(tokio::test)]
329 async fn stream_partial() -> anyhow::Result<()> {
330 let s = ready_then_pending(vec![1_u8, 2], vec![3]);
331 let b = ready_then_pending(Bytes::from("foo"), Bytes::from("bar"));
332 let r: Pin<Box<dyn AsyncRead + Send>> = Box::pin(StreamReader::new(
333 ready_then_pending(Bytes::from("foo"), Bytes::from("bar")).map(Ok::<_, std::io::Error>),
334 ));
335 let mut buf = BytesMut::default();
336 pack((s, b, r), &mut buf).await?;
337 assert_eq!(
338 buf.as_ref(),
339 b"\x01\x03\x01\x02\x03\x01\x06foobar\x01\x06foobar"
340 );
341 Ok(())
342 }
343
344 #[test_log::test(tokio::test)]
345 async fn pending_future() -> anyhow::Result<()> {
346 let fut: Pin<Box<dyn Future<Output = u8> + Send>> = Box::pin(pending());
347 let mut buf = BytesMut::default();
348 let res = tokio::time::timeout(Duration::from_millis(10), pack(fut, &mut buf)).await;
349 assert!(res.is_err());
350 Ok(())
351 }
352
353 #[test]
354 fn ready_values() -> anyhow::Result<()> {
355 let fut = ready(0x42_u8).boxed();
356 let s = stream::iter([Bytes::from("foo")]).boxed();
357 let mut buf = BytesMut::default();
358 pack_ready((0x01_u8, fut, s), &mut buf)?;
359 assert_eq!(buf.as_ref(), b"\x01\x01\x42\x01\x03foo");
360 Ok(())
361 }
362
363 #[test]
364 fn ready_nested() -> anyhow::Result<()> {
365 let s = stream::iter((0..=255_u8).map(|i| vec![ready(i).boxed()])).boxed();
366 let mut buf = BytesMut::default();
367 pack_ready(s, &mut buf)?;
368 let expected: Vec<u8> = [0x01, 0x80, 0x02]
369 .into_iter()
370 .chain((0..=255).flat_map(|i| [0x01, i]))
371 .collect();
372 assert_eq!(buf.as_ref(), expected);
373 Ok(())
374 }
375
376 #[test]
377 fn ready_pending() {
378 let fut = ready(pending::<u8>().boxed()).boxed();
379 let mut buf = BytesMut::default();
380 let err = pack_ready(fut, &mut buf).unwrap_err();
381 assert_eq!(err.kind(), std::io::ErrorKind::WouldBlock);
382 }
383
384 #[test]
385 fn unpack_trailing() {
386 let mut buf = BytesMut::from(&b"\x42\x00"[..]);
387 let err = unpack::<u8>(&mut buf).err().unwrap();
388 assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
389 }
390
391 #[test_log::test(tokio::test)]
392 async fn unpack_pending() {
393 let mut buf = BytesMut::from(&b"\x00"[..]);
394 let err = unpack::<Pin<Box<dyn Future<Output = u8> + Send>>>(&mut buf)
395 .err()
396 .unwrap();
397 assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
398
399 let mut buf = BytesMut::from(&b"\x00"[..]);
400 let err = unpack::<Pin<Box<dyn Stream<Item = Vec<u8>> + Send>>>(&mut buf)
401 .err()
402 .unwrap();
403 assert_eq!(err.kind(), std::io::ErrorKind::InvalidData);
404 }
405}