simple_hyper_client/body/
mod.rs1use self::shared::{SharedBody, SharedBuf};
8
9use http_body_util::combinators::BoxBody;
10use http_body_util::BodyExt;
11use hyper::body::{Body, Buf, Bytes, Frame, SizeHint};
12
13use std::error::Error;
14use std::pin::Pin;
15use std::task::{Context, Poll};
16
17pub(crate) mod shared;
18
19pub struct RequestBody(InnerBody);
26
27enum InnerBody {
28 Shared(SharedBody),
29 Wrapped(BoxBody<Bytes, Box<dyn Error + Send + Sync>>),
30}
31
32impl RequestBody {
33 pub fn empty() -> Self {
35 SharedBody::empty().into()
36 }
37
38 pub fn wrap<B, E>(body: B) -> Self
40 where
41 B: Body<Data = Bytes, Error = E> + Send + Sync + 'static,
42 E: Error + Send + Sync + 'static,
43 {
44 Self(InnerBody::Wrapped(
50 body.map_err(|e| Box::new(e) as Box<dyn Error + Send + Sync>)
51 .boxed(),
52 ))
53 }
54}
55
56impl Default for RequestBody {
57 #[inline]
59 fn default() -> Self {
60 Self::empty()
61 }
62}
63
64impl<T: Into<SharedBody>> From<T> for RequestBody {
65 fn from(shared_body: T) -> Self {
66 Self(InnerBody::Shared(shared_body.into()))
67 }
68}
69
70impl Body for RequestBody {
71 type Data = Buffer;
72 type Error = Box<dyn Error + Send + Sync>;
73
74 fn poll_frame(
75 self: Pin<&mut Self>,
76 cx: &mut Context<'_>,
77 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
78 match &mut self.get_mut().0 {
79 InnerBody::Shared(shared_body) => SharedBody::poll_frame(Pin::new(shared_body), cx)
80 .map(|opt| {
81 opt.map(|res| {
82 res.map(|frame| frame.map_data(|bytes| Buffer::Shared(bytes)))
83 .map_err(|e| Box::new(e) as Box<dyn Error + Send + Sync>)
84 })
85 }),
86
87 InnerBody::Wrapped(box_body) => {
88 BoxBody::poll_frame(Pin::new(box_body), cx).map(|opt| {
89 opt.map(|res| res.map(|frame| frame.map_data(|bytes| Buffer::Wrapped(bytes))))
90 })
91 }
92 }
93 }
94
95 fn is_end_stream(&self) -> bool {
96 match &self.0 {
97 InnerBody::Shared(shared_body) => shared_body.is_end_stream(),
98 InnerBody::Wrapped(box_body) => box_body.is_end_stream(),
99 }
100 }
101
102 fn size_hint(&self) -> SizeHint {
103 match &self.0 {
104 InnerBody::Shared(shared_body) => shared_body.size_hint(),
105 InnerBody::Wrapped(box_body) => box_body.size_hint(),
106 }
107 }
108}
109
110pub enum Buffer {
112 Shared(SharedBuf),
113 Wrapped(Bytes),
114}
115
116impl Buf for Buffer {
117 fn remaining(&self) -> usize {
118 match self {
119 Self::Shared(shared_buf) => shared_buf.remaining(),
120 Self::Wrapped(bytes) => bytes.remaining(),
121 }
122 }
123
124 fn chunk(&self) -> &[u8] {
125 match self {
126 Self::Shared(shared_buf) => shared_buf.chunk(),
127 Self::Wrapped(bytes) => bytes.chunk(),
128 }
129 }
130
131 fn advance(&mut self, cnt: usize) {
132 match self {
133 Self::Shared(shared_buf) => shared_buf.advance(cnt),
134 Self::Wrapped(bytes) => bytes.advance(cnt),
135 }
136 }
137}