Skip to main content

sark_http/payload/response/body/
mod.rs

1use 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
13/// Statically dispatched response payload.
14pub 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}