1use crate::{AsyncSeekForward, SeekForward};
2use async_trait::async_trait;
3use futures::io::{AsyncRead, AsyncReadExt};
4use std::io::Read;
5use std::io::Result as IOResult;
6use std::pin::Pin;
7use std::task::{Context, Poll};
8
9pub struct Discarder<R: Read> {
11 reader: R,
12}
13
14impl<R: Read> Discarder<R> {
15 pub fn new(reader: R) -> Self {
16 Self { reader }
17 }
18
19 pub fn into_inner(self) -> R {
20 self.reader
21 }
22}
23
24impl<R: Read> Read for Discarder<R> {
25 fn read(&mut self, buf: &mut [u8]) -> IOResult<usize> {
26 self.reader.read(buf)
27 }
28}
29
30impl<R: Read> SeekForward for Discarder<R> {
31 fn seek_forward(&mut self, forward: u64) -> IOResult<()> {
32 let mut buf = [0; 4096];
33 let mut left = forward as usize;
34 while left > 0 {
35 let toread = left.min(buf.len());
36 let r = self.reader.read(&mut buf[0..toread])?;
37 left -= r;
38 }
39 Ok(())
40 }
41}
42
43pub struct AsyncDiscarder<R: AsyncRead> {
44 reader: R,
45}
46
47impl<R: AsyncRead> AsyncDiscarder<R> {
48 pub fn new(reader: R) -> Self {
49 Self { reader }
50 }
51
52 pub fn into_inner(self) -> R {
53 self.reader
54 }
55}
56
57impl<R: AsyncRead + Unpin> AsyncRead for AsyncDiscarder<R> {
58 fn poll_read(
59 mut self: Pin<&mut Self>,
60 cx: &mut Context<'_>,
61 buf: &mut [u8],
62 ) -> Poll<IOResult<usize>> {
63 Pin::new(&mut self.reader).poll_read(cx, buf)
64 }
65}
66
67#[async_trait]
68impl<R: AsyncRead + Unpin + Send> AsyncSeekForward for AsyncDiscarder<R> {
69 async fn async_seek_forward(&mut self, forward: u64) -> IOResult<()> {
70 let mut buf = [0; 4096];
71 let mut left = forward as usize;
72 while left > 0 {
73 let toread = left.min(buf.len());
74 let r = self.read(&mut buf[0..toread]).await?;
75 left -= r;
76 }
77 Ok(())
78 }
79}
80
81#[cfg(test)]
82mod test {
83 use super::*;
84 use std::slice;
85
86 #[test]
87 fn discard() {
88 let mut data = Vec::with_capacity(256);
89 for byte in 0u8..=255 {
90 data.push(byte);
91 }
92
93 let mut discarder = Discarder::new(data.as_slice());
94 let _ = &[0u64, 5, 16, 31, 63, 200, 255]
95 .iter()
96 .fold(0, |pos, offset| {
97 let mut byte: u8 = 1;
98 discarder.seek_forward(offset - pos).unwrap();
99 assert_eq!(1, discarder.read(slice::from_mut(&mut byte)).unwrap());
100 assert_eq!(*offset, byte as u64);
101 *offset + 1
102 });
103 }
104}