servlin/
body_async_reader.rs1use crate::event::EventReceiver;
2use std::io::{Cursor, Read};
3use std::path::Path;
4use std::pin::Pin;
5use std::sync::Mutex;
6use std::task::{Context, Poll};
7
8pub enum BodyAsyncReader<'x> {
10 Cursor(Cursor<&'x [u8]>),
11 EventReceiver(&'x Mutex<EventReceiver>),
12 File(async_fs::File),
13}
14impl<'x> BodyAsyncReader<'x> {
15 #[must_use]
16 pub fn bytes(bytes: &'x [u8]) -> Self {
17 Self::Cursor(Cursor::new(bytes))
18 }
19
20 pub async fn file(path: impl AsRef<Path>) -> Result<BodyAsyncReader<'x>, std::io::Error> {
23 let file = async_fs::File::open(path.as_ref()).await?;
24 Ok(BodyAsyncReader::File(file))
25 }
26}
27impl futures_io::AsyncRead for BodyAsyncReader<'_> {
28 fn poll_read(
29 mut self: Pin<&mut Self>,
30 cx: &mut Context<'_>,
31 buf: &mut [u8],
32 ) -> Poll<Result<usize, std::io::Error>> {
33 match &mut *self {
34 BodyAsyncReader::Cursor(cursor) => Poll::Ready(cursor.read(buf)),
35 BodyAsyncReader::EventReceiver(mutex_event_receiver) =>
36 {
37 #[allow(clippy::mut_mutex_lock)]
38 Pin::new(&mut *mutex_event_receiver.lock().unwrap()).poll_read(cx, buf)
39 }
40 BodyAsyncReader::File(async_fs_file) => Pin::new(async_fs_file).poll_read(cx, buf),
41 }
42 }
43}