1use std::{borrow::Borrow, marker::PhantomData};
2
3use o3::buffer::bytes::scope;
4
5use crate::{
6 owner::handoff::{Origin, Project, Slot, origin, stage},
7 payload::owned,
8 request::body::{self, Source as _},
9};
10
11pub struct Borrowed<'a, S>(&'a mut S);
13
14impl<'a, S> Borrowed<'a, S> {
15 pub const fn new(source: &'a mut S) -> Self {
16 Self(source)
17 }
18}
19
20impl<'a, 'd, S: body::Source<'d>> Project<'d> for Borrowed<'a, S> {
21 type Proof = ();
22 type Owner = ();
23
24 fn contiguous<V, T>(
25 self,
26 value: V,
27 project: impl for<'req> FnOnce(
28 V,
29 body::View<'req, 'd>,
30 Slot<'req, 'd, (), Bound<'req, 'd, ()>>,
31 ) -> T,
32 ) -> Result<(T, ()), (Self, V, body::Error)> {
33 match self.0.try_project(value, |value, view| {
34 project(value, view, Bound::slot(view.into(), ()))
35 }) {
36 Ok(output) => Ok((output, ())),
37 Err((value, error)) => Err((self, value, error)),
38 }
39 }
40
41 fn segmented<V, T>(
42 self,
43 value: V,
44 project: impl for<'req> FnOnce(
45 V,
46 body::Ref<'req, 'd>,
47 Slot<'req, 'd, (), Bound<'req, 'd, ()>>,
48 ) -> T,
49 ) -> (T, ()) {
50 let view = self.0.body().into();
51 (project(value, view, Bound::slot(view, ())), ())
52 }
53
54 fn discarded<V, T>(
55 self,
56 value: V,
57 project: impl for<'req> FnOnce(V, Slot<'req, 'd, (), Bound<'req, 'd, ()>>) -> T,
58 ) -> (T, ()) {
59 (
60 project(value, Bound::slot(body::Ref::from_slice(&[]), ())),
61 (),
62 )
63 }
64}
65
66pub struct Input<'owner, 'd>(scope::Owner<'owner, ()>, owned::Segments<'d>);
68
69pub struct Frozen<'owner, 'd>(Input<'owner, 'd>);
71
72#[derive(Clone, Copy)]
74pub struct Bound<'req, 'd, P> {
75 body: body::Retained<'req, 'd>,
76 proof: P,
77}
78
79#[derive(Clone, Copy)]
81pub struct Selected<'owner>(PhantomData<*mut &'owner ()>);
82
83impl<'d> Input<'_, 'd> {
84 pub fn with<T>(
85 source: owned::Segments<'d>,
86 run: impl for<'owner> FnOnce(Input<'owner, 'd>) -> T,
87 ) -> T {
88 scope::Owner::with((), |brand| run(Input(brand, source)))
89 }
90}
91
92impl<'req, 'd, P: stage::Proof> Bound<'req, 'd, P> {
93 fn slot(view: body::Ref<'req, 'd>, proof: P) -> Slot<'req, 'd, (), Self> {
94 let source = match view.try_retained() {
95 Ok(body) => origin::Source::Retained(Self { body, proof }),
96 Err(body) if body.is_empty() => origin::Source::Empty,
97 Err(_) => origin::Source::Borrowed(PhantomData),
98 };
99 Slot {
100 origin: Origin { source },
101 head: (),
102 }
103 }
104}
105
106impl<'owner, 'd> Project<'d> for Input<'owner, 'd> {
107 type Proof = Selected<'owner>;
108 type Owner = Frozen<'owner, 'd>;
109
110 fn contiguous<V, T>(
111 mut self,
112 value: V,
113 project: impl for<'req> FnOnce(
114 V,
115 body::View<'req, 'd>,
116 Slot<'req, 'd, (), Bound<'req, 'd, Selected<'owner>>>,
117 ) -> T,
118 ) -> Result<(T, Self::Owner), (Self, V, body::Error)> {
119 let output = self.1.try_project(value, |value, view| {
120 project(value, view, Bound::slot(view.into(), Selected(PhantomData)))
121 });
122 match output {
123 Ok(output) => Ok((output, Frozen(self))),
124 Err((value, error)) => Err((self, value, error)),
125 }
126 }
127
128 fn segmented<V, T>(
129 self,
130 value: V,
131 project: impl for<'req> FnOnce(
132 V,
133 body::Ref<'req, 'd>,
134 Slot<'req, 'd, (), Bound<'req, 'd, Selected<'owner>>>,
135 ) -> T,
136 ) -> (T, Self::Owner) {
137 let view = body::Ref::from(&self.1);
138 let output = project(value, view, Bound::slot(view, Selected(PhantomData)));
139 (output, Frozen(self))
140 }
141
142 fn discarded<V, T>(
143 self,
144 value: V,
145 project: impl for<'req> FnOnce(V, Slot<'req, 'd, (), Bound<'req, 'd, Selected<'owner>>>) -> T,
146 ) -> (T, Self::Owner) {
147 let output = project(
148 value,
149 Bound::slot(body::Ref::from_slice(&[]), Selected(PhantomData)),
150 );
151 (output, Frozen(self))
152 }
153}
154
155impl<'req, 'd, P> Borrow<body::Retained<'req, 'd>> for Bound<'req, 'd, P> {
156 fn borrow(&self) -> &body::Retained<'req, 'd> {
157 &self.body
158 }
159}
160
161impl<'req, 'd: 'req, P: stage::Proof> stage::Body<'req, 'd> for Bound<'req, 'd, P> {
162 type Deferred = P::Deferred;
163
164 fn defer(self) -> Self::Deferred {
165 self.proof.defer(self.body)
166 }
167}
168
169impl stage::Proof for Selected<'_> {
170 type Deferred = Self;
171
172 fn defer(self, _: body::Retained<'_, '_>) -> Self {
173 self
174 }
175}
176
177impl<'owner, 'd> stage::Deferred<'d> for Selected<'owner> {
178 type Owner = Frozen<'owner, 'd>;
179
180 fn resolve(self, owner: Self::Owner) -> owned::Segments<'d> {
181 let Input(brand, body) = owner.0;
182 brand.into_inner();
183 body
184 }
185}
186
187const _: () = {
188 assert!(size_of::<Input<'static, 'static>>() == size_of::<owned::Segments<'static>>());
189 assert!(size_of::<Frozen<'static, 'static>>() == size_of::<owned::Segments<'static>>());
190 assert!(
191 size_of::<Bound<'static, 'static, Selected<'static>>>()
192 == size_of::<body::Retained<'static, 'static>>()
193 );
194 assert!(size_of::<Selected<'static>>() == 0);
195};