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