1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use core::{cmp::min, pin::Pin, task::{Context, Poll}};
use crate::io;
pub struct AsyncSliceReader<'b>{
buf: &'b [u8],
cur: usize,
}
impl Unpin for AsyncSliceReader<'_> {}
impl<'b> AsyncSliceReader<'b> {
pub fn new(buf: &'b [u8]) -> Self {
Self { buf, cur: 0 }
}
pub fn bytes_read(&self) -> usize {
self.cur
}
fn consume(&mut self, amt: usize) {
self.cur += min(self.bytes_available(), amt);
}
fn bytes_available(&self) -> usize {
self.buf.len() - self.cur
}
fn read_into(&mut self, buf: &mut [u8]) -> usize {
let n = min(self.bytes_available(), buf.len());
if n > 0 {
buf[..n].copy_from_slice(&self.buf[self.cur..self.cur + n]);
self.cur += n;
}
n
}
}
impl io::AsyncRead for AsyncSliceReader<'_> {
fn poll_read(mut self: Pin<&mut Self>, _cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<io::Result<usize>> {
Poll::Ready(Ok(self.read_into(buf)))
}
}
impl io::AsyncBufRead for AsyncSliceReader<'_>{
fn poll_fill_buf(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
Poll::Ready(Ok(&self.buf[self.cur..]))
}
fn consume(mut self: Pin<&mut Self>, amt: usize) {
(&mut *self).consume(amt);
}
}
impl<'b> From<&'b [u8]> for AsyncSliceReader<'b> {
fn from(buf: &'b [u8]) -> Self {
Self{ buf, cur: 0 }
}
}
impl<'b> From<&'b super::AsyncSliceWriter<'b>> for AsyncSliceReader<'b> {
fn from(s: &'b super::AsyncSliceWriter<'b>) -> Self {
Self{ buf: s.as_written(), cur: 0 }
}
}
#[cfg(test)]
mod test {
use futures::{AsyncReadExt, executor::block_on};
use super::*;
#[test]
fn can_read_from_vec() {
const LEN: usize = 10;
let send = [7u8; LEN];
let mut reader = AsyncSliceReader::new(&send);
assert!(reader.bytes_read() == 0);
let mut recv = [0u8; LEN];
let result = block_on(reader.read(&mut recv));
assert!(result.is_ok());
assert!(reader.bytes_read() == LEN);
assert!(recv == send)
}
}