1pub mod buffered;
2pub mod identity;
3pub mod reservation;
4pub mod send;
5
6use std::io;
7
8use dope_core::driver::DriverRef;
9use dope_core::driver::ready::ReadyKey;
10use dope_core::driver::token::Token;
11use o3::buffer::{Borrowed, Retained};
12
13use self::send::{Plain, Prepared, SendStorage, Sent, Storage, Vectored};
14pub use dope_core::io::recv::{Lease, View};
15
16use crate::{Bytes, RetainBytes};
17
18pub enum Reclaim {
19 OnSubmit,
20 OnComplete,
21}
22
23pub enum RecvChunk<'a, R> {
24 Borrowed(Bytes<Borrowed<'a>>),
26 Owned(R),
28}
29
30pub struct RecvTarget<'a> {
35 buffer: &'a mut Vec<u8>,
36 limit: usize,
37}
38
39impl<'a> RecvTarget<'a> {
40 pub fn new(buffer: &'a mut Vec<u8>) -> Self {
41 buffer.clear();
42 let limit = buffer.capacity();
43 Self { buffer, limit }
44 }
45
46 pub fn len(&self) -> usize {
47 self.buffer.len()
48 }
49
50 pub fn is_empty(&self) -> bool {
51 self.buffer.is_empty()
52 }
53
54 pub fn remaining(&self) -> usize {
55 self.limit - self.buffer.len()
56 }
57
58 pub fn write_prefix(&mut self, source: &[u8]) -> usize {
59 let amount = source.len().min(self.remaining());
60 self.buffer.extend_from_slice(&source[..amount]);
61 amount
62 }
63
64 #[doc(hidden)]
65 pub fn with_limit(&mut self, limit: usize, fill: impl FnOnce(&mut RecvTarget<'_>)) -> usize {
66 let initial = self.buffer.len();
67 let previous = self.limit;
68 self.limit = initial + limit.min(self.remaining());
69 fill(self);
70 self.limit = previous;
71 self.buffer.len() - initial
72 }
73}
74
75pub trait RecvCursor: Unpin {
78 fn remaining(&self) -> usize;
79
80 fn read_into(&mut self, target: &mut RecvTarget<'_>);
82
83 fn is_empty(&self) -> bool {
84 self.remaining() == 0
85 }
86}
87
88impl RecvCursor for Bytes<Retained> {
89 fn remaining(&self) -> usize {
90 self.len()
91 }
92
93 fn read_into(&mut self, target: &mut RecvTarget<'_>) {
94 let count = target.write_prefix(self.as_slice());
95 self.consume_prefix_up_to(count);
96 }
97}
98
99impl RecvCursor for View<'_> {
100 fn remaining(&self) -> usize {
101 self.len()
102 }
103
104 fn read_into(&mut self, target: &mut RecvTarget<'_>) {
105 let count = target.write_prefix(self.as_slice());
106 self.advance(count);
107 }
108}
109
110#[must_use]
115pub struct RecvCredit<'d> {
116 driver: DriverRef<'d>,
117 ready: ReadyKey<'d>,
118 target: Token,
119}
120
121#[must_use]
125pub struct RecvCreditGuard<'d>(RecvCredit<'d>);
126
127impl<'d> RecvCredit<'d> {
128 pub(crate) fn new(driver: DriverRef<'d>, ready: ReadyKey<'d>, target: Token) -> Self {
129 Self {
130 driver,
131 ready,
132 target,
133 }
134 }
135
136 pub fn claim(self) -> Result<RecvCreditGuard<'d>, Self> {
137 if !self.driver.arm_recv_credit(self.ready, self.target) {
138 return Err(self);
139 }
140 Ok(RecvCreditGuard(self))
141 }
142}
143
144impl Drop for RecvCreditGuard<'_> {
145 fn drop(&mut self) {
146 self.0
147 .driver
148 .release_recv_credit(self.0.ready, self.0.target);
149 }
150}
151
152#[derive(Clone, Copy)]
153pub struct RuntimeLimits {
154 max_connections: usize,
155 max_retained_recv_chunks: usize,
156 max_recv_len: usize,
157 recv_credit: bool,
158}
159
160impl RuntimeLimits {
161 pub fn new(
162 max_connections: usize,
163 max_retained_recv_chunks: usize,
164 max_recv_len: usize,
165 ) -> Self {
166 Self {
167 max_connections,
168 max_retained_recv_chunks,
169 max_recv_len,
170 recv_credit: false,
171 }
172 }
173
174 #[doc(hidden)]
175 pub fn with_recv_credit(mut self) -> Self {
176 self.recv_credit = true;
177 self
178 }
179
180 pub fn max_connections(self) -> usize {
181 self.max_connections
182 }
183
184 pub fn max_retained_recv_chunks(self) -> usize {
185 self.max_retained_recv_chunks
186 }
187
188 pub fn max_recv_len(self) -> usize {
189 self.max_recv_len
190 }
191
192 pub fn recv_credit(self) -> bool {
193 self.recv_credit
194 }
195}
196
197pub trait Wire: 'static + Sized {
198 type Connection<'d>: 'd
200 where
201 Self: 'd;
202 type ConnectionStorage: 'static;
204 type InitConfig<'d>: 'd
205 where
206 Self: 'd;
207 type RuntimeContext<'d>: 'd
208 where
209 Self: 'd;
210 type Open<'a, 'd>: OpenReservation<Self::Connection<'d>, Self::SendStorage>
211 where
212 'd: 'a;
213 type OpenError: std::error::Error + Send + Sync + 'static;
218 type Recv<'a>: RetainBytes + 'a;
219 type RecvBatch<'a>: ExactSizeIterator<Item = RecvChunk<'a, Self::Recv<'a>>>
220 where
221 Self: 'a;
222 type RetainedRecv<'d>: RecvCursor + 'd
223 where
224 Self: 'd;
225 type SendStorage: SendStorage;
226
227 const RECLAIM: Reclaim;
228
229 const RAW_RECV: bool = false;
230
231 const RECV_CREDIT: bool = false;
233
234 fn connection_storage(capacity: usize) -> io::Result<Self::ConnectionStorage>;
235
236 fn runtime_context<'d>(
237 limits: RuntimeLimits,
238 config: Self::InitConfig<'d>,
239 ) -> io::Result<Self::RuntimeContext<'d>>
240 where
241 Self: 'd;
242
243 fn prepare_open<'a, 'd>(
249 runtime: &'a mut Self::RuntimeContext<'d>,
250 ) -> Result<Option<Self::Open<'a, 'd>>, Self::OpenError>
251 where
252 'd: 'a;
253
254 fn holds_plain<'d>(_wire: &Self::Connection<'d>, _send: &Self::SendStorage) -> bool {
255 false
256 }
257
258 fn process_recv<'a, 'd>(
261 wire: &mut Self::Connection<'d>,
262 runtime: &mut Self::RuntimeContext<'d>,
263 bytes: &'a mut [u8],
264 ) -> Self::RecvBatch<'a>;
265
266 fn process_retained_recv<'a, 'd>(
270 wire: &mut Self::Connection<'d>,
271 runtime: &mut Self::RuntimeContext<'d>,
272 bytes: Lease<'a>,
273 ) -> Option<Self::RetainedRecv<'a>>;
274
275 fn bind_recv_credit<'d>(
282 recv: &mut Self::RetainedRecv<'d>,
283 credit: RecvCredit<'d>,
284 ) -> Result<(), RecvCredit<'d>> {
285 let _ = recv;
286 Err(credit)
287 }
288
289 fn recv_eof<'d>(_wire: &mut Self::Connection<'d>) {}
290
291 fn prepare_send<'a, 'd>(
292 wire: &'a mut Self::Connection<'d>,
293 send: Storage<'a, Self::SendStorage>,
294 plain: Plain<'a>,
295 ) -> Prepared<'a>;
296
297 fn prepare_send_vectored<'a, 'd>(
298 wire: &'a mut Self::Connection<'d>,
299 send: Storage<'a, Self::SendStorage>,
300 plain: Vectored<'a>,
301 ) -> Prepared<'a>;
302
303 fn submit_failed<'d>(_wire: &mut Self::Connection<'d>) {}
304
305 fn after_send<'a, 'd>(
306 wire: &'a mut Self::Connection<'d>,
307 send: Storage<'a, Self::SendStorage>,
308 sent: Sent,
309 ) -> Prepared<'a>;
310
311 fn flush_pending<'a, 'd>(
312 wire: &'a mut Self::Connection<'d>,
313 send: Storage<'a, Self::SendStorage>,
314 ) -> Prepared<'a>;
315
316 fn graceful_close<'a, 'd>(
317 _wire: &'a mut Self::Connection<'d>,
318 send: Storage<'a, Self::SendStorage>,
319 ) -> Prepared<'a> {
320 send.empty(0)
321 }
322}
323
324pub trait OpenReservation<W, S> {
325 fn commit(self) -> (W, S);
326}
327
328pub trait OpenRollback<W, S> {
329 fn rollback_open(&mut self, open: (W, S));
330}
331
332pub struct ReadyOpen<W, S> {
333 committed: (W, S),
334}
335
336impl<W, S> ReadyOpen<W, S> {
337 pub fn new(wire: W, send: S) -> Self {
338 Self {
339 committed: (wire, send),
340 }
341 }
342}
343
344impl<W, S> OpenReservation<W, S> for ReadyOpen<W, S> {
345 fn commit(self) -> (W, S) {
346 self.committed
347 }
348}