http_body/
frame.rs

1use http::HeaderMap;
2
3/// A frame of any kind related to an HTTP stream (body).
4#[derive(Debug)]
5pub struct Frame<T> {
6    kind: Kind<T>,
7}
8
9#[derive(Debug)]
10enum Kind<T> {
11    // The first two variants are "inlined" since they are undoubtedly
12    // the most common. This saves us from having to allocate a
13    // boxed trait object for them.
14    Data(T),
15    Trailers(HeaderMap),
16    //Unknown(Box<dyn Frameish>),
17}
18
19impl<T> Frame<T> {
20    /// Create a DATA frame with the provided `Buf`.
21    pub fn data(buf: T) -> Self {
22        Self {
23            kind: Kind::Data(buf),
24        }
25    }
26
27    /// Create a trailers frame.
28    pub fn trailers(map: HeaderMap) -> Self {
29        Self {
30            kind: Kind::Trailers(map),
31        }
32    }
33
34    /// Maps this frame's data to a different type.
35    pub fn map_data<F, D>(self, f: F) -> Frame<D>
36    where
37        F: FnOnce(T) -> D,
38    {
39        match self.kind {
40            Kind::Data(data) => Frame {
41                kind: Kind::Data(f(data)),
42            },
43            Kind::Trailers(trailers) => Frame {
44                kind: Kind::Trailers(trailers),
45            },
46        }
47    }
48
49    /// Returns whether this is a DATA frame.
50    pub fn is_data(&self) -> bool {
51        matches!(self.kind, Kind::Data(..))
52    }
53
54    /// Consumes self into the buf of the DATA frame.
55    ///
56    /// Returns an [`Err`] containing the original [`Frame`] when frame is not a DATA frame.
57    /// `Frame::is_data` can also be used to determine if the frame is a DATA frame.
58    pub fn into_data(self) -> Result<T, Self> {
59        match self.kind {
60            Kind::Data(data) => Ok(data),
61            _ => Err(self),
62        }
63    }
64
65    /// If this is a DATA frame, returns a reference to it.
66    ///
67    /// Returns `None` if not a DATA frame.
68    pub fn data_ref(&self) -> Option<&T> {
69        match self.kind {
70            Kind::Data(ref data) => Some(data),
71            _ => None,
72        }
73    }
74
75    /// If this is a DATA frame, returns a mutable reference to it.
76    ///
77    /// Returns `None` if not a DATA frame.
78    pub fn data_mut(&mut self) -> Option<&mut T> {
79        match self.kind {
80            Kind::Data(ref mut data) => Some(data),
81            _ => None,
82        }
83    }
84
85    /// Returns whether this is a trailers frame.
86    pub fn is_trailers(&self) -> bool {
87        matches!(self.kind, Kind::Trailers(..))
88    }
89
90    /// Consumes self into the buf of the trailers frame.
91    ///
92    /// Returns an [`Err`] containing the original [`Frame`] when frame is not a trailers frame.
93    /// `Frame::is_trailers` can also be used to determine if the frame is a trailers frame.
94    pub fn into_trailers(self) -> Result<HeaderMap, Self> {
95        match self.kind {
96            Kind::Trailers(trailers) => Ok(trailers),
97            _ => Err(self),
98        }
99    }
100
101    /// If this is a trailers frame, returns a reference to it.
102    ///
103    /// Returns `None` if not a trailers frame.
104    pub fn trailers_ref(&self) -> Option<&HeaderMap> {
105        match self.kind {
106            Kind::Trailers(ref trailers) => Some(trailers),
107            _ => None,
108        }
109    }
110
111    /// If this is a trailers frame, returns a mutable reference to it.
112    ///
113    /// Returns `None` if not a trailers frame.
114    pub fn trailers_mut(&mut self) -> Option<&mut HeaderMap> {
115        match self.kind {
116            Kind::Trailers(ref mut trailers) => Some(trailers),
117            _ => None,
118        }
119    }
120}