sark_http/payload/response/body/
mod.rs1use std::{iter::FusedIterator, ops::ControlFlow};
2
3use o3::buffer::{bytes::scope, storage, write::Slice};
4
5use crate::{
6 owner::{handoff, handoff::stage},
7 payload::owned,
8};
9
10mod sealed;
11pub(crate) use sealed::Sealed;
12
13pub trait Body<'d>: Sized + Sealed {
15 #[doc(hidden)]
16 const INLINE: bool = false;
17
18 fn len(&self) -> usize;
19
20 fn is_empty(&self) -> bool {
21 self.len() == 0
22 }
23
24 fn as_slice(&self) -> Option<&[u8]>;
25
26 fn segments(&self) -> impl ExactSizeIterator<Item = &[u8]> + FusedIterator {
27 self.as_slice().filter(|body| !body.is_empty()).into_iter()
28 }
29
30 #[doc(hidden)]
31 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
32 self,
33 slot: &handoff::Slot<'req, 'd, H, O>,
34 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error>;
35
36 #[doc(hidden)]
37 fn try_resolve_into<
38 'req,
39 H: scope::Source,
40 O: stage::Body<'req, 'd>,
41 L: std::borrow::BorrowMut<usize>,
42 >(
43 self,
44 slot: &handoff::Slot<'req, 'd, H, O>,
45 _: &mut Slice<'_, L>,
46 ) -> Result<ControlFlow<usize, handoff::Plan<'req, 'd, H::Selection, O>>, owned::Error> {
47 self.try_resolve(slot).map(ControlFlow::Continue)
48 }
49}
50
51impl<'d> Body<'d> for [u8; 0] {
52 const INLINE: bool = true;
53
54 fn len(&self) -> usize {
55 <[u8]>::len(self)
56 }
57
58 fn as_slice(&self) -> Option<&[u8]> {
59 Some(self)
60 }
61
62 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
63 self,
64 slot: &handoff::Slot<'req, 'd, H, O>,
65 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
66 match self {
67 [] => Ok(handoff::Plan::new(slot.origin().clear())),
68 }
69 }
70}
71
72impl<'d> Body<'d> for &[u8] {
73 const INLINE: bool = true;
74
75 fn len(&self) -> usize {
76 <[u8]>::len(self)
77 }
78
79 fn as_slice(&self) -> Option<&[u8]> {
80 Some(self)
81 }
82
83 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
84 self,
85 slot: &handoff::Slot<'req, 'd, H, O>,
86 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
87 handoff::Plan::try_borrow(slot, self)
88 }
89
90 fn try_resolve_into<
91 'req,
92 H: scope::Source,
93 O: stage::Body<'req, 'd>,
94 L: std::borrow::BorrowMut<usize>,
95 >(
96 self,
97 slot: &handoff::Slot<'req, 'd, H, O>,
98 out: &mut Slice<'_, L>,
99 ) -> Result<ControlFlow<usize, handoff::Plan<'req, 'd, H::Selection, O>>, owned::Error> {
100 handoff::Plan::try_borrow_into(slot, self, out)
101 }
102}
103
104impl<'d> Body<'d> for &str {
105 const INLINE: bool = true;
106
107 fn len(&self) -> usize {
108 str::len(self)
109 }
110
111 fn as_slice(&self) -> Option<&[u8]> {
112 Some(self.as_bytes())
113 }
114
115 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
116 self,
117 slot: &handoff::Slot<'req, 'd, H, O>,
118 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
119 handoff::Plan::try_borrow(slot, self.as_bytes())
120 }
121
122 fn try_resolve_into<
123 'req,
124 H: scope::Source,
125 O: stage::Body<'req, 'd>,
126 L: std::borrow::BorrowMut<usize>,
127 >(
128 self,
129 slot: &handoff::Slot<'req, 'd, H, O>,
130 out: &mut Slice<'_, L>,
131 ) -> Result<ControlFlow<usize, handoff::Plan<'req, 'd, H::Selection, O>>, owned::Error> {
132 handoff::Plan::try_borrow_into(slot, self.as_bytes(), out)
133 }
134}
135
136impl<'d> Body<'d> for Vec<u8> {
137 const INLINE: bool = true;
138
139 fn len(&self) -> usize {
140 self.as_slice().len()
141 }
142
143 fn as_slice(&self) -> Option<&[u8]> {
144 Some(self.as_slice())
145 }
146
147 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
148 self,
149 slot: &handoff::Slot<'req, 'd, H, O>,
150 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
151 Ok(handoff::Plan::new(slot.origin().owned(self)))
152 }
153}
154
155impl<'d> Body<'d> for String {
156 const INLINE: bool = true;
157
158 fn len(&self) -> usize {
159 String::len(self)
160 }
161
162 fn as_slice(&self) -> Option<&[u8]> {
163 Some(self.as_bytes())
164 }
165
166 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
167 self,
168 slot: &handoff::Slot<'req, 'd, H, O>,
169 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
170 Ok(handoff::Plan::new(slot.origin().owned(self.into_bytes())))
171 }
172}
173
174impl<'d> Body<'d> for storage::Owned {
175 fn len(&self) -> usize {
176 self.as_ref().len()
177 }
178
179 fn as_slice(&self) -> Option<&[u8]> {
180 Some(self.as_ref())
181 }
182
183 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
184 self,
185 slot: &handoff::Slot<'req, 'd, H, O>,
186 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
187 Ok(handoff::Plan::new(slot.origin().shared(self.freeze())))
188 }
189}
190
191impl<'d> Body<'d> for storage::Shared {
192 fn len(&self) -> usize {
193 self.as_ref().len()
194 }
195
196 fn as_slice(&self) -> Option<&[u8]> {
197 Some(self.as_ref())
198 }
199
200 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
201 self,
202 slot: &handoff::Slot<'req, 'd, H, O>,
203 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
204 Ok(handoff::Plan::new(slot.origin().shared(self)))
205 }
206}