Skip to content

Commit 6a2e600

Browse files
committed
chore(http/retry): vendor http_body::Frame<T>
this vendors a copy of the `Frame<T>` type. we can use this to preemptively model our peek body in terms of this type, and move to the "real" version of it when we're upgrading in #3504. Signed-off-by: katelyn martin <[email protected]>
1 parent f049ca8 commit 6a2e600

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

linkerd/http/retry/src/frame.rs

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

linkerd/http/retry/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
pub mod peek_trailers;
55
pub mod replay;
66

7+
mod frame;
8+
79
pub use self::{peek_trailers::PeekTrailersBody, replay::ReplayBody};
810
pub use tower::retry::budget::Budget;
911

0 commit comments

Comments
 (0)