Skip to main content

sark_http/payload/response/body/
mod.rs

1use 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
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
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}