1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use bytes::Bytes;
use futures::Stream;
use hyper::body::{Body, Chunk};
use std::borrow::Cow;
use std::error::Error as StdError;
use std::str;
use input;
#[derive(Debug)]
pub struct ResponseBody(pub(crate) ResponseBodyKind);
#[derive(Debug)]
pub(crate) enum ResponseBodyKind {
Empty,
Sized(Bytes),
Chunked(Body),
}
impl Default for ResponseBody {
fn default() -> Self {
ResponseBody(ResponseBodyKind::Empty)
}
}
impl From<()> for ResponseBody {
fn from(_: ()) -> Self {
ResponseBody(ResponseBodyKind::Empty)
}
}
impl From<Body> for ResponseBody {
fn from(body: Body) -> Self {
ResponseBody(ResponseBodyKind::Chunked(body))
}
}
impl From<input::body::Chunk> for ResponseBody {
fn from(chunk: input::body::Chunk) -> Self {
ResponseBody(ResponseBodyKind::Sized(chunk.0.into_bytes()))
}
}
impl From<Chunk> for ResponseBody {
fn from(chunk: Chunk) -> Self {
ResponseBody(ResponseBodyKind::Sized(chunk.into_bytes()))
}
}
macro_rules! impl_conversions {
($($t:ty,)*) => {$(
impl From<$t> for ResponseBody {
fn from(body: $t) -> Self {
ResponseBody(ResponseBodyKind::Sized(body.into()))
}
}
)*};
}
impl_conversions![&'static str, &'static [u8], String, Vec<u8>, Bytes,];
impl From<Cow<'static, str>> for ResponseBody {
fn from(body: Cow<'static, str>) -> Self {
match body {
Cow::Borrowed(bytes) => bytes.into(),
Cow::Owned(bytes) => bytes.into(),
}
}
}
impl From<Cow<'static, [u8]>> for ResponseBody {
fn from(body: Cow<'static, [u8]>) -> Self {
match body {
Cow::Borrowed(bytes) => bytes.into(),
Cow::Owned(bytes) => bytes.into(),
}
}
}
impl ResponseBody {
pub fn empty() -> ResponseBody {
Default::default()
}
pub fn wrap_stream<S>(stream: S) -> ResponseBody
where
S: Stream + Send + 'static,
S::Error: Into<Box<dyn StdError + Send + Sync + 'static>>,
Chunk: From<S::Item>,
{
ResponseBody(ResponseBodyKind::Chunked(Body::wrap_stream(stream)))
}
pub(crate) fn content_length(&self) -> Option<usize> {
match self.0 {
ResponseBodyKind::Empty => Some(0),
ResponseBodyKind::Sized(ref bytes) => Some(bytes.len()),
_ => None,
}
}
pub(crate) fn into_hyp(self) -> Body {
match self.0 {
ResponseBodyKind::Empty => Body::empty(),
ResponseBodyKind::Sized(bytes) => Body::from(bytes),
ResponseBodyKind::Chunked(body) => body,
}
}
}