simple_hyper_client/
shared_body.rs1use headers::HeaderMap;
8use hyper::body::{Buf, HttpBody};
9
10use std::pin::Pin;
11use std::sync::Arc;
12use std::task::{Context, Poll};
13use std::{cmp, io};
14
15pub struct SharedBody(Option<InnerBuf>);
20
21enum InnerBuf {
22 Arc(Arc<Vec<u8>>),
23 Static(&'static [u8]),
24}
25
26impl AsRef<[u8]> for SharedBody {
27 fn as_ref(&self) -> &[u8] {
28 match self.0.as_ref() {
29 Some(InnerBuf::Arc(vec)) => vec,
30 Some(InnerBuf::Static(slice)) => slice,
31 None => &[],
32 }
33 }
34}
35
36impl SharedBody {
37 pub fn len(&self) -> usize {
38 match self.0.as_ref() {
39 Some(InnerBuf::Arc(vec)) => vec.len(),
40 Some(InnerBuf::Static(slice)) => slice.len(),
41 None => 0,
42 }
43 }
44
45 pub fn empty() -> Self {
46 SharedBody(None)
47 }
48}
49
50impl Default for SharedBody {
51 #[inline]
53 fn default() -> Self {
54 SharedBody::empty()
55 }
56}
57
58impl From<Arc<Vec<u8>>> for SharedBody {
59 fn from(arc: Arc<Vec<u8>>) -> Self {
60 SharedBody(Some(InnerBuf::Arc(arc)))
61 }
62}
63
64impl From<Vec<u8>> for SharedBody {
65 fn from(vec: Vec<u8>) -> Self {
66 SharedBody(Some(InnerBuf::Arc(Arc::new(vec))))
67 }
68}
69
70impl From<String> for SharedBody {
71 fn from(s: String) -> Self {
72 SharedBody(Some(InnerBuf::Arc(Arc::new(s.into_bytes()))))
73 }
74}
75
76impl From<&'static [u8]> for SharedBody {
77 fn from(slice: &'static [u8]) -> Self {
78 SharedBody(Some(InnerBuf::Static(slice)))
79 }
80}
81
82impl From<&'static str> for SharedBody {
83 fn from(s: &'static str) -> Self {
84 SharedBody(Some(InnerBuf::Static(s.as_bytes())))
85 }
86}
87
88impl HttpBody for SharedBody {
89 type Data = SharedBuf;
90 type Error = io::Error;
91
92 fn poll_data(
93 self: Pin<&mut Self>,
94 _cx: &mut Context<'_>,
95 ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
96 let opt = self
97 .get_mut()
98 .0
99 .take()
100 .map(|bytes| SharedBuf { bytes, pos: 0 })
101 .map(Ok);
102 Poll::Ready(opt)
103 }
104
105 fn poll_trailers(
106 self: Pin<&mut Self>,
107 _cx: &mut Context<'_>,
108 ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
109 Poll::Ready(Ok(None))
110 }
111}
112
113pub struct SharedBuf {
114 bytes: InnerBuf,
115 pos: usize,
116}
117
118impl SharedBuf {
119 fn len(&self) -> usize {
120 match self.bytes {
121 InnerBuf::Arc(ref bytes) => bytes.len(),
122 InnerBuf::Static(ref bytes) => bytes.len(),
123 }
124 }
125}
126
127impl Buf for SharedBuf {
128 fn remaining(&self) -> usize {
129 self.len() - self.pos
130 }
131
132 fn chunk(&self) -> &[u8] {
133 match self.bytes {
134 InnerBuf::Arc(ref bytes) => &bytes[self.pos..],
135 InnerBuf::Static(ref bytes) => &bytes[self.pos..],
136 }
137 }
138
139 fn advance(&mut self, cnt: usize) {
140 self.pos = cmp::min(self.len(), self.pos + cnt);
141 }
142}