sark_core/http/response/
body.rs1use o3::buffer::{Borrowed, Bytes, Owned, Retained, Shared};
2
3use super::TextBody;
4
5#[derive(Clone)]
6pub enum Body<'req> {
7 Owned(Vec<u8>),
8 Shared(Shared),
9 Borrowed(Bytes<Borrowed<'req>>),
10 Retained(Bytes<Retained>),
11 StaticSlice(&'static [u8]),
12}
13
14impl<'req> std::fmt::Debug for Body<'req> {
15 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16 match self {
17 Self::Owned(buf) => f
18 .debug_struct("Body::Owned")
19 .field("len", &buf.len())
20 .finish(),
21 Self::Shared(buf) => f
22 .debug_struct("Body::Shared")
23 .field("len", &buf.len())
24 .finish(),
25 Self::Borrowed(buf) => f
26 .debug_struct("Body::Borrowed")
27 .field("len", &buf.len())
28 .finish(),
29 Self::Retained(buf) => f
30 .debug_struct("Body::Retained")
31 .field("len", &buf.len())
32 .finish(),
33 Self::StaticSlice(buf) => f
34 .debug_struct("Body::StaticSlice")
35 .field("len", &buf.len())
36 .finish(),
37 }
38 }
39}
40
41impl<'req> Body<'req> {
42 pub(crate) fn empty() -> Self {
43 Self::Owned(Vec::new())
44 }
45
46 pub(crate) fn len(&self) -> usize {
47 match self {
48 Self::Owned(buf) => buf.len(),
49 Self::Shared(buf) => buf.len(),
50 Self::Borrowed(buf) => buf.len(),
51 Self::Retained(buf) => buf.len(),
52 Self::StaticSlice(buf) => buf.len(),
53 }
54 }
55
56 pub(crate) fn as_bytes(&self) -> &[u8] {
57 match self {
58 Self::Owned(buf) => buf.as_ref(),
59 Self::Shared(buf) => buf.as_ref(),
60 Self::Borrowed(buf) => buf.as_slice(),
61 Self::Retained(buf) => buf.as_slice(),
62 Self::StaticSlice(buf) => buf,
63 }
64 }
65
66 pub(crate) fn is_shared(&self) -> bool {
67 matches!(
68 self,
69 Self::Shared(_) | Self::Borrowed(_) | Self::Retained(_) | Self::StaticSlice(_)
70 )
71 }
72
73 pub(crate) fn into_bytes(self) -> Shared {
74 match self {
75 Self::Owned(buf) => Shared::from(buf),
76 Self::Shared(buf) => buf,
77 Self::Borrowed(buf) => Shared::copy_from_slice(buf.as_slice()),
78 Self::Retained(buf) => buf.into_shared(),
79 Self::StaticSlice(buf) => Shared::from_static(buf),
80 }
81 }
82
83 pub(crate) fn into_owned(self) -> Vec<u8> {
84 match self {
85 Self::Owned(buf) => buf,
86 Self::Shared(buf) => buf.as_ref().to_vec(),
87 Self::Borrowed(buf) => buf.as_slice().to_vec(),
88 Self::Retained(buf) => buf.as_slice().to_vec(),
89 Self::StaticSlice(buf) => buf.to_vec(),
90 }
91 }
92
93 pub(crate) fn as_owned_mut(&mut self) -> &mut Vec<u8> {
94 if matches!(
95 self,
96 Self::Shared(_) | Self::Borrowed(_) | Self::Retained(_) | Self::StaticSlice(_)
97 ) {
98 let old = std::mem::replace(self, Self::empty());
99 *self = Self::Owned(old.into_owned());
100 }
101 match self {
102 Self::Owned(buf) => buf,
103 _ => unreachable!("response body must be owned after conversion"),
104 }
105 }
106}
107
108impl<'req> From<Owned> for Body<'req> {
109 fn from(body: Owned) -> Self {
110 Self::Shared(body.freeze())
111 }
112}
113
114impl<'req> From<Shared> for Body<'req> {
115 fn from(body: Shared) -> Self {
116 Self::Shared(body)
117 }
118}
119
120impl<'req> From<Bytes<Borrowed<'req>>> for Body<'req> {
121 fn from(body: Bytes<Borrowed<'req>>) -> Self {
122 Self::Borrowed(body)
123 }
124}
125
126impl<'req> From<Bytes<Retained>> for Body<'req> {
127 fn from(body: Bytes<Retained>) -> Self {
128 Self::Retained(body)
129 }
130}
131
132impl<'req> From<TextBody<'req>> for Body<'req> {
133 fn from(body: TextBody<'req>) -> Self {
134 Self::Shared(body.into_bytes())
135 }
136}
137
138impl<'req> From<Vec<u8>> for Body<'req> {
139 fn from(body: Vec<u8>) -> Self {
140 Self::Owned(body)
141 }
142}
143
144impl<'req> From<String> for Body<'req> {
145 fn from(body: String) -> Self {
146 Self::Owned(body.into_bytes())
147 }
148}
149
150impl<'req> From<&[u8]> for Body<'req> {
151 fn from(body: &[u8]) -> Self {
152 Self::Owned(body.to_vec())
153 }
154}
155
156impl<'req> From<&str> for Body<'req> {
157 fn from(body: &str) -> Self {
158 Self::Owned(body.as_bytes().to_vec())
159 }
160}