Skip to main content

compio_io/ancillary/
io.rs

1#[cfg(feature = "allocator_api")]
2use std::alloc::Allocator;
3
4use compio_buf::{BufResult, IoBuf, IoBufMut, IoVectoredBuf, IoVectoredBufMut, t_alloc};
5use futures_util::Stream;
6
7use crate::{AsyncReadManaged, IoResult};
8
9/// Trait for asynchronous read with ancillary (control) data.
10/// Intended for connected stream sockets (TCP, Unix streams) where no source
11/// address is needed.
12pub trait AsyncReadAncillary {
13    /// Read data with ancillary data into an owned buffer.
14    async fn read_with_ancillary<T: IoBufMut, C: IoBufMut>(
15        &mut self,
16        buffer: T,
17        control: C,
18    ) -> BufResult<(usize, usize), (T, C)>;
19
20    /// Read data with ancillary data into a vectored buffer.
21    async fn read_vectored_with_ancillary<T: IoVectoredBufMut, C: IoBufMut>(
22        &mut self,
23        buffer: T,
24        control: C,
25    ) -> BufResult<(usize, usize), (T, C)>;
26}
27
28impl<A: AsyncReadAncillary + ?Sized> AsyncReadAncillary for &mut A {
29    #[inline]
30    async fn read_with_ancillary<T: IoBufMut, C: IoBufMut>(
31        &mut self,
32        buffer: T,
33        control: C,
34    ) -> BufResult<(usize, usize), (T, C)> {
35        (**self).read_with_ancillary(buffer, control).await
36    }
37
38    #[inline]
39    async fn read_vectored_with_ancillary<T: IoVectoredBufMut, C: IoBufMut>(
40        &mut self,
41        buffer: T,
42        control: C,
43    ) -> BufResult<(usize, usize), (T, C)> {
44        (**self).read_vectored_with_ancillary(buffer, control).await
45    }
46}
47
48impl<A: AsyncReadAncillary + ?Sized, #[cfg(feature = "allocator_api")] Alloc: Allocator>
49    AsyncReadAncillary for t_alloc!(Box, A, Alloc)
50{
51    #[inline]
52    async fn read_with_ancillary<T: IoBufMut, C: IoBufMut>(
53        &mut self,
54        buffer: T,
55        control: C,
56    ) -> BufResult<(usize, usize), (T, C)> {
57        (**self).read_with_ancillary(buffer, control).await
58    }
59
60    #[inline]
61    async fn read_vectored_with_ancillary<T: IoVectoredBufMut, C: IoBufMut>(
62        &mut self,
63        buffer: T,
64        control: C,
65    ) -> BufResult<(usize, usize), (T, C)> {
66        (**self).read_vectored_with_ancillary(buffer, control).await
67    }
68}
69
70/// Trait for asynchronous write with ancillary (control) data.
71/// Intended for connected stream sockets (TCP, Unix streams) where no
72/// destination address is needed.
73pub trait AsyncWriteAncillary {
74    /// Write data with ancillary data from an owned buffer.
75    async fn write_with_ancillary<T: IoBuf, C: IoBuf>(
76        &mut self,
77        buffer: T,
78        control: C,
79    ) -> BufResult<usize, (T, C)>;
80
81    /// Write data with ancillary data from a vectored buffer.
82    async fn write_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
83        &mut self,
84        buffer: T,
85        control: C,
86    ) -> BufResult<usize, (T, C)>;
87}
88
89impl<A: AsyncWriteAncillary + ?Sized> AsyncWriteAncillary for &mut A {
90    #[inline]
91    async fn write_with_ancillary<T: IoBuf, C: IoBuf>(
92        &mut self,
93        buffer: T,
94        control: C,
95    ) -> BufResult<usize, (T, C)> {
96        (**self).write_with_ancillary(buffer, control).await
97    }
98
99    #[inline]
100    async fn write_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
101        &mut self,
102        buffer: T,
103        control: C,
104    ) -> BufResult<usize, (T, C)> {
105        (**self)
106            .write_vectored_with_ancillary(buffer, control)
107            .await
108    }
109}
110
111impl<A: AsyncWriteAncillary + ?Sized, #[cfg(feature = "allocator_api")] Alloc: Allocator>
112    AsyncWriteAncillary for t_alloc!(Box, A, Alloc)
113{
114    #[inline]
115    async fn write_with_ancillary<T: IoBuf, C: IoBuf>(
116        &mut self,
117        buffer: T,
118        control: C,
119    ) -> BufResult<usize, (T, C)> {
120        (**self).write_with_ancillary(buffer, control).await
121    }
122
123    #[inline]
124    async fn write_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
125        &mut self,
126        buffer: T,
127        control: C,
128    ) -> BufResult<usize, (T, C)> {
129        (**self)
130            .write_vectored_with_ancillary(buffer, control)
131            .await
132    }
133}
134
135/// Trait for zerocopy asynchronous write with ancillary (control) data.
136/// Intended for connected stream sockets (TCP, Unix streams) where no
137/// destination address is needed.
138pub trait AsyncWriteAncillaryZerocopy {
139    /// The future that will be resolved when the buffer is safe to be reused.
140    type BufferReadyFuture<T: IoBuf, C: IoBuf>: Future<Output = (T, C)>;
141    /// The future that will be resolved when the vectored buffer is safe to be
142    /// reused.
143    type VectoredBufferReadyFuture<T: IoVectoredBuf, C: IoBuf>: Future<Output = (T, C)>;
144
145    /// Write some bytes from buffer into this source using the underlying
146    /// zero-copy mechanism. It returns a result of the underlying write
147    /// operation and a future that will be resolved when the buffer is safe
148    /// to be reused.
149    fn write_zerocopy_with_ancillary<T: IoBuf, C: IoBuf>(
150        &mut self,
151        buf: T,
152        control: C,
153    ) -> impl Future<Output = BufResult<usize, Self::BufferReadyFuture<T, C>>>;
154
155    /// Like `write_zerocopy_with_ancillary`, except that it writes from a
156    /// buffer implements [`IoVectoredBuf`] into the source.
157    fn write_zerocopy_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
158        &mut self,
159        buf: T,
160        control: C,
161    ) -> impl Future<Output = BufResult<usize, Self::VectoredBufferReadyFuture<T, C>>>;
162}
163
164impl<A: AsyncWriteAncillaryZerocopy + ?Sized> AsyncWriteAncillaryZerocopy for &mut A {
165    type BufferReadyFuture<T: IoBuf, C: IoBuf> = A::BufferReadyFuture<T, C>;
166    type VectoredBufferReadyFuture<T: IoVectoredBuf, C: IoBuf> = A::VectoredBufferReadyFuture<T, C>;
167
168    #[inline]
169    fn write_zerocopy_with_ancillary<T: IoBuf, C: IoBuf>(
170        &mut self,
171        buf: T,
172        control: C,
173    ) -> impl Future<Output = BufResult<usize, Self::BufferReadyFuture<T, C>>> {
174        (**self).write_zerocopy_with_ancillary(buf, control)
175    }
176
177    #[inline]
178    fn write_zerocopy_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
179        &mut self,
180        buf: T,
181        control: C,
182    ) -> impl Future<Output = BufResult<usize, Self::VectoredBufferReadyFuture<T, C>>> {
183        (**self).write_zerocopy_vectored_with_ancillary(buf, control)
184    }
185}
186
187impl<A: AsyncWriteAncillaryZerocopy + ?Sized, #[cfg(feature = "allocator_api")] Alloc: Allocator>
188    AsyncWriteAncillaryZerocopy for t_alloc!(Box, A, Alloc)
189{
190    type BufferReadyFuture<T: IoBuf, C: IoBuf> = A::BufferReadyFuture<T, C>;
191    type VectoredBufferReadyFuture<T: IoVectoredBuf, C: IoBuf> = A::VectoredBufferReadyFuture<T, C>;
192
193    fn write_zerocopy_with_ancillary<T: IoBuf, C: IoBuf>(
194        &mut self,
195        buf: T,
196        control: C,
197    ) -> impl Future<Output = BufResult<usize, Self::BufferReadyFuture<T, C>>> {
198        (**self).write_zerocopy_with_ancillary(buf, control)
199    }
200
201    fn write_zerocopy_vectored_with_ancillary<T: IoVectoredBuf, C: IoBuf>(
202        &mut self,
203        buf: T,
204        control: C,
205    ) -> impl Future<Output = BufResult<usize, Self::VectoredBufferReadyFuture<T, C>>> {
206        (**self).write_zerocopy_vectored_with_ancillary(buf, control)
207    }
208}
209
210/// Trait for asynchronous read with ancillary (control) data that returns
211/// managed buffers. Intended for connected stream sockets (TCP, Unix streams)
212/// where no source address is needed.
213pub trait AsyncReadAncillaryManaged: AsyncReadManaged {
214    /// Read data into a managed buffer with ancillary data.
215    ///
216    /// # Implementation Note
217    ///
218    /// - If `len` == 0, implementation should use buffer's size as `len`
219    /// - if `len` > 0, `min(len, buffer_size)` will be the max number of bytes
220    ///   to be read.
221    async fn read_managed_with_ancillary<C: IoBufMut>(
222        &mut self,
223        len: usize,
224        control: C,
225    ) -> IoResult<Option<(Self::Buffer, C)>>;
226}
227
228/// Trait for asynchronous read with ancillary (control) data that returns
229/// multiple managed buffers. Intended for connected stream sockets (TCP, Unix
230/// streams) where no source address is needed.
231pub trait AsyncReadAncillaryMulti {
232    /// A wrapped type for the payload data and the ancillary data.
233    type Return;
234
235    /// Read data and ancillary data into multiple managed buffers.
236    fn read_multi_with_ancillary(
237        &mut self,
238        control_len: usize,
239    ) -> impl Stream<Item = IoResult<Self::Return>>;
240}