hyper_staticfile/
body.rs

1use std::{
2    io::Error as IoError,
3    pin::Pin,
4    task::{ready, Context, Poll},
5};
6
7use futures_util::stream::Stream;
8use hyper::body::{Bytes, Frame};
9
10use crate::{
11    util::{FileBytesStream, FileBytesStreamMultiRange, FileBytesStreamRange},
12    vfs::{FileAccess, TokioFileAccess},
13};
14
15/// Hyper Body implementation for the various types of streams used in static serving.
16pub enum Body<F = TokioFileAccess> {
17    /// No response body.
18    Empty,
19    /// Serve a complete file.
20    Full(FileBytesStream<F>),
21    /// Serve a range from a file.
22    Range(FileBytesStreamRange<F>),
23    /// Serve multiple ranges from a file.
24    MultiRange(FileBytesStreamMultiRange<F>),
25}
26
27impl<F: FileAccess> hyper::body::Body for Body<F> {
28    type Data = Bytes;
29    type Error = IoError;
30
31    fn poll_frame(
32        mut self: Pin<&mut Self>,
33        cx: &mut Context<'_>,
34    ) -> Poll<Option<Result<Frame<Bytes>, IoError>>> {
35        let opt = ready!(match *self {
36            Body::Empty => return Poll::Ready(None),
37            Body::Full(ref mut stream) => Pin::new(stream).poll_next(cx),
38            Body::Range(ref mut stream) => Pin::new(stream).poll_next(cx),
39            Body::MultiRange(ref mut stream) => Pin::new(stream).poll_next(cx),
40        });
41        Poll::Ready(opt.map(|res| res.map(Frame::data)))
42    }
43}