+221
Diff
round #2
+220
libs/kasync/src/io.rs
+220
libs/kasync/src/io.rs
···
1
+
// Copyright 2025. Jonas Kruckenberg
2
+
//
3
+
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4
+
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5
+
// http://opensource.org/licenses/MIT>, at your option. This file may not be
6
+
// copied, modified, or distributed except according to those terms.
7
+
8
+
use core::cmp;
9
+
use core::convert::Infallible;
10
+
use core::ops::{Deref, DerefMut};
11
+
use core::pin::Pin;
12
+
use core::task::{Context, Poll, ready};
13
+
14
+
pub trait Read {
15
+
type Err: core::error::Error;
16
+
17
+
// Pull some bytes from this source into the specified buffer.
18
+
fn poll_read(
19
+
self: Pin<&mut Self>,
20
+
cx: &mut Context<'_>,
21
+
buf: &mut [u8],
22
+
) -> Poll<Result<usize, Self::Err>>;
23
+
24
+
// Attempt to read from the AsyncRead into bufs using vectored IO operations.
25
+
//
26
+
// This method is similar to poll_read, but allows data to be read into multiple buffers using a single operation.
27
+
//
28
+
// On success, returns Poll::Ready(Ok(num_bytes_read)).
29
+
fn poll_read_vectored(
30
+
mut self: Pin<&mut Self>,
31
+
cx: &mut Context<'_>,
32
+
bufs: &mut [&mut [u8]],
33
+
) -> Poll<Result<usize, Self::Err>> {
34
+
let mut nread = 0;
35
+
for b in bufs {
36
+
if !b.is_empty() {
37
+
nread += ready!(self.as_mut().poll_read(cx, b)?);
38
+
}
39
+
}
40
+
Poll::Ready(Ok(nread))
41
+
}
42
+
}
43
+
44
+
pub trait Write {
45
+
type Err: core::error::Error;
46
+
47
+
// Writes a buffer into this writer.
48
+
//
49
+
// returning how many bytes were written.
50
+
fn poll_write(
51
+
self: Pin<&mut Self>,
52
+
cx: &mut Context<'_>,
53
+
buf: &[u8],
54
+
) -> Poll<Result<usize, Self::Err>>;
55
+
56
+
// Flushes this output stream, ensuring that all intermediately buffered contents reach their destination.
57
+
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>>;
58
+
59
+
// Attempt to close the object.
60
+
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>>;
61
+
62
+
// Attempt to write bytes from bufs into the object using vectored IO operations.
63
+
//
64
+
// This method is similar to poll_write, but allows data from multiple buffers to be written using a single operation.
65
+
//
66
+
// On success, returns Poll::Ready(Ok(num_bytes_written)).
67
+
fn poll_write_vectored(
68
+
mut self: Pin<&mut Self>,
69
+
cx: &mut Context<'_>,
70
+
bufs: &[&[u8]],
71
+
) -> Poll<Result<usize, Self::Err>> {
72
+
let mut nwritten = 0;
73
+
for b in bufs {
74
+
if !b.is_empty() {
75
+
nwritten += ready!(self.as_mut().poll_write(cx, b)?);
76
+
}
77
+
}
78
+
Poll::Ready(Ok(nwritten))
79
+
}
80
+
}
81
+
82
+
// ===== impl Read =====
83
+
84
+
impl Read for &[u8] {
85
+
type Err = Infallible;
86
+
87
+
fn poll_read(
88
+
self: Pin<&mut Self>,
89
+
_cx: &mut Context<'_>,
90
+
buf: &mut [u8],
91
+
) -> Poll<Result<usize, Self::Err>> {
92
+
let amt = cmp::min(buf.len(), self.len());
93
+
let (a, b) = self.split_at(amt);
94
+
95
+
// First check if the amount of bytes we want to read is small:
96
+
// `copy_from_slice` will generally expand to a call to `memcpy`, and
97
+
// for a single byte the overhead is significant.
98
+
if amt == 1 {
99
+
buf[0] = a[0];
100
+
} else {
101
+
buf[..amt].copy_from_slice(a);
102
+
}
103
+
104
+
*self.get_mut() = b;
105
+
106
+
Poll::Ready(Ok(amt))
107
+
}
108
+
}
109
+
110
+
impl<P> Read for Pin<P>
111
+
where
112
+
P: DerefMut + Unpin,
113
+
<P as Deref>::Target: Read,
114
+
{
115
+
type Err = <P::Target as Read>::Err;
116
+
117
+
fn poll_read(
118
+
self: Pin<&mut Self>,
119
+
cx: &mut Context<'_>,
120
+
buf: &mut [u8],
121
+
) -> Poll<Result<usize, Self::Err>> {
122
+
self.get_mut().as_mut().poll_read(cx, buf)
123
+
}
124
+
125
+
fn poll_read_vectored(
126
+
self: Pin<&mut Self>,
127
+
cx: &mut Context<'_>,
128
+
bufs: &mut [&mut [u8]],
129
+
) -> Poll<Result<usize, Self::Err>> {
130
+
self.get_mut().as_mut().poll_read_vectored(cx, bufs)
131
+
}
132
+
}
133
+
134
+
impl<T> Read for &mut T
135
+
where
136
+
T: Read + Unpin + ?Sized,
137
+
{
138
+
type Err = T::Err;
139
+
140
+
fn poll_read(
141
+
mut self: Pin<&mut Self>,
142
+
cx: &mut Context<'_>,
143
+
buf: &mut [u8],
144
+
) -> Poll<Result<usize, Self::Err>> {
145
+
Pin::new(&mut **self).poll_read(cx, buf)
146
+
}
147
+
148
+
fn poll_read_vectored(
149
+
mut self: Pin<&mut Self>,
150
+
cx: &mut Context<'_>,
151
+
bufs: &mut [&mut [u8]],
152
+
) -> Poll<Result<usize, Self::Err>> {
153
+
Pin::new(&mut **self).poll_read_vectored(cx, bufs)
154
+
}
155
+
}
156
+
157
+
// ===== impl Write =====
158
+
159
+
impl<P> Write for Pin<P>
160
+
where
161
+
P: DerefMut + Unpin,
162
+
<P as Deref>::Target: Write,
163
+
{
164
+
type Err = <P::Target as Write>::Err;
165
+
166
+
fn poll_write(
167
+
self: Pin<&mut Self>,
168
+
cx: &mut Context<'_>,
169
+
buf: &[u8],
170
+
) -> Poll<Result<usize, Self::Err>> {
171
+
self.get_mut().as_mut().poll_write(cx, buf)
172
+
}
173
+
174
+
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>> {
175
+
self.get_mut().as_mut().poll_flush(cx)
176
+
}
177
+
178
+
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>> {
179
+
self.get_mut().as_mut().poll_close(cx)
180
+
}
181
+
182
+
fn poll_write_vectored(
183
+
self: Pin<&mut Self>,
184
+
cx: &mut Context<'_>,
185
+
bufs: &[&[u8]],
186
+
) -> Poll<Result<usize, Self::Err>> {
187
+
self.get_mut().as_mut().poll_write_vectored(cx, bufs)
188
+
}
189
+
}
190
+
191
+
impl<T> Write for &mut T
192
+
where
193
+
T: Write + Unpin + ?Sized,
194
+
{
195
+
type Err = T::Err;
196
+
197
+
fn poll_write(
198
+
mut self: Pin<&mut Self>,
199
+
cx: &mut Context<'_>,
200
+
buf: &[u8],
201
+
) -> Poll<Result<usize, Self::Err>> {
202
+
Pin::new(&mut **self).poll_write(cx, buf)
203
+
}
204
+
205
+
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>> {
206
+
Pin::new(&mut **self).poll_flush(cx)
207
+
}
208
+
209
+
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Err>> {
210
+
Pin::new(&mut **self).poll_close(cx)
211
+
}
212
+
213
+
fn poll_write_vectored(
214
+
mut self: Pin<&mut Self>,
215
+
cx: &mut Context<'_>,
216
+
bufs: &[&[u8]],
217
+
) -> Poll<Result<usize, Self::Err>> {
218
+
Pin::new(&mut **self).poll_write_vectored(cx, bufs)
219
+
}
220
+
}
History
3 rounds
0 comments
jonaskruckenberg.de
submitted
#2
1 commit
expand
collapse
feat: async IO traits
no conflicts, ready to merge
expand 0 comments
jonaskruckenberg.de
submitted
#1
1 commit
expand
collapse
feat: async IO traits
expand 0 comments
jonaskruckenberg.de
submitted
#0
1 commit
expand
collapse
feat: async IO traits