saluki_io/net/util/
http.rs

1use std::{
2    convert::Infallible,
3    pin::Pin,
4    task::{Context, Poll},
5};
6
7use bytes::{Buf, Bytes};
8use http_body::{Body, Frame};
9
10use crate::buf::ReadIoBuffer;
11
12/// A fixed-sized HTTP body based on a single input buffer.
13#[derive(Clone)]
14pub struct FixedBody {
15    data: Option<Bytes>,
16}
17
18impl FixedBody {
19    /// Create a new `FixedBody` from the given data.
20    pub fn new<D: Into<Bytes>>(data: D) -> Self {
21        Self {
22            data: Some(data.into()),
23        }
24    }
25}
26
27impl Buf for FixedBody {
28    fn remaining(&self) -> usize {
29        self.data.as_ref().map_or(0, |data| data.remaining())
30    }
31
32    fn chunk(&self) -> &[u8] {
33        self.data.as_ref().map_or(&[], |data| data.chunk())
34    }
35
36    fn advance(&mut self, cnt: usize) {
37        match self.data.as_mut() {
38            Some(data) => data.advance(cnt),
39            None => panic!("attempted to advance a consumed body"),
40        }
41    }
42}
43
44impl ReadIoBuffer for FixedBody {
45    fn capacity(&self) -> usize {
46        self.data.as_ref().map_or(0, |data| data.capacity())
47    }
48}
49
50impl Body for FixedBody {
51    type Data = Bytes;
52    type Error = Infallible;
53
54    fn poll_frame(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
55        Poll::Ready(self.get_mut().data.take().map(|data| Ok(Frame::data(data))))
56    }
57}