sark_http/payload/response/body/
mod.rs1use std::iter::FusedIterator;
2
3use o3::buffer::{bytes::scope, storage};
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
37impl<'d> Body<'d> for [u8; 0] {
38 const INLINE: bool = true;
39
40 fn len(&self) -> usize {
41 <[u8]>::len(self)
42 }
43
44 fn as_slice(&self) -> Option<&[u8]> {
45 Some(self)
46 }
47
48 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
49 self,
50 slot: &handoff::Slot<'req, 'd, H, O>,
51 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
52 match self {
53 [] => Ok(handoff::Plan::new(slot.origin().clear())),
54 }
55 }
56}
57
58impl<'d> Body<'d> for &[u8] {
59 const INLINE: bool = true;
60
61 fn len(&self) -> usize {
62 <[u8]>::len(self)
63 }
64
65 fn as_slice(&self) -> Option<&[u8]> {
66 Some(self)
67 }
68
69 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
70 self,
71 slot: &handoff::Slot<'req, 'd, H, O>,
72 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
73 handoff::Plan::try_borrow(slot, self)
74 }
75}
76
77impl<'d> Body<'d> for &str {
78 const INLINE: bool = true;
79
80 fn len(&self) -> usize {
81 str::len(self)
82 }
83
84 fn as_slice(&self) -> Option<&[u8]> {
85 Some(self.as_bytes())
86 }
87
88 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
89 self,
90 slot: &handoff::Slot<'req, 'd, H, O>,
91 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
92 handoff::Plan::try_borrow(slot, self.as_bytes())
93 }
94}
95
96impl<'d> Body<'d> for Vec<u8> {
97 const INLINE: bool = true;
98
99 fn len(&self) -> usize {
100 self.as_slice().len()
101 }
102
103 fn as_slice(&self) -> Option<&[u8]> {
104 Some(self.as_slice())
105 }
106
107 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
108 self,
109 slot: &handoff::Slot<'req, 'd, H, O>,
110 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
111 Ok(handoff::Plan::new(slot.origin().owned(self)))
112 }
113}
114
115impl<'d> Body<'d> for String {
116 const INLINE: bool = true;
117
118 fn len(&self) -> usize {
119 String::len(self)
120 }
121
122 fn as_slice(&self) -> Option<&[u8]> {
123 Some(self.as_bytes())
124 }
125
126 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
127 self,
128 slot: &handoff::Slot<'req, 'd, H, O>,
129 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
130 Ok(handoff::Plan::new(slot.origin().owned(self.into_bytes())))
131 }
132}
133
134impl<'d> Body<'d> for storage::Owned {
135 fn len(&self) -> usize {
136 self.as_ref().len()
137 }
138
139 fn as_slice(&self) -> Option<&[u8]> {
140 Some(self.as_ref())
141 }
142
143 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
144 self,
145 slot: &handoff::Slot<'req, 'd, H, O>,
146 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
147 Ok(handoff::Plan::new(slot.origin().shared(self.freeze())))
148 }
149}
150
151impl<'d> Body<'d> for storage::Shared {
152 fn len(&self) -> usize {
153 self.as_ref().len()
154 }
155
156 fn as_slice(&self) -> Option<&[u8]> {
157 Some(self.as_ref())
158 }
159
160 fn try_resolve<'req, H: scope::Source, O: stage::Body<'req, 'd>>(
161 self,
162 slot: &handoff::Slot<'req, 'd, H, O>,
163 ) -> Result<handoff::Plan<'req, 'd, H::Selection, O>, owned::Error> {
164 Ok(handoff::Plan::new(slot.origin().shared(self)))
165 }
166}