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}