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 into_shared(self) -> Shared {
86 self.into_bytes()
87 }
88
89 pub(crate) fn into_owned(self) -> Vec<u8> {
90 match self {
91 Self::Owned(buf) => buf,
92 Self::Shared(buf) => buf.as_ref().to_vec(),
93 Self::Borrowed(buf) => buf.as_slice().to_vec(),
94 Self::Retained(buf) => buf.as_slice().to_vec(),
95 Self::StaticSlice(buf) => buf.to_vec(),
96 }
97 }
98
99 pub(crate) fn as_owned_mut(&mut self) -> &mut Vec<u8> {
100 if matches!(
101 self,
102 Self::Shared(_) | Self::Borrowed(_) | Self::Retained(_) | Self::StaticSlice(_)
103 ) {
104 let old = std::mem::replace(self, Self::empty());
105 *self = Self::Owned(old.into_owned());
106 }
107 match self {
108 Self::Owned(buf) => buf,
109 _ => unreachable!("response body must be owned after conversion"),
110 }
111 }
112}
113
114impl<'req> From<Owned> for Body<'req> {
115 fn from(body: Owned) -> Self {
116 Self::Shared(body.freeze())
117 }
118}
119
120impl<'req> From<Shared> for Body<'req> {
121 fn from(body: Shared) -> Self {
122 Self::Shared(body)
123 }
124}
125
126impl<'req> From<Bytes<Borrowed<'req>>> for Body<'req> {
127 fn from(body: Bytes<Borrowed<'req>>) -> Self {
128 Self::Borrowed(body)
129 }
130}
131
132impl<'req> From<Bytes<Retained>> for Body<'req> {
133 fn from(body: Bytes<Retained>) -> Self {
134 Self::Retained(body)
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}