Skip to main content

nuclei/io/util/
misc.rs

1//! Readers and writers with nothing behind them: [`empty`], [`repeat`] and
2//! [`sink`].
3
4use core::pin::Pin;
5use core::task::{Context, Poll};
6use std::io;
7
8use futures_io::{AsyncBufRead, AsyncRead, AsyncWrite};
9
10/// A reader at its end at once, and a writer that takes every byte and
11/// keeps none. Made by [`empty`].
12#[derive(Clone, Copy, Debug, Default)]
13pub struct Empty {
14    _private: (),
15}
16
17/// A reader at its end at once, and a writer that takes every byte and
18/// keeps none.
19pub fn empty() -> Empty {
20    Empty { _private: () }
21}
22
23impl AsyncRead for Empty {
24    fn poll_read(
25        self: Pin<&mut Self>,
26        _: &mut Context<'_>,
27        _: &mut [u8],
28    ) -> Poll<io::Result<usize>> {
29        Poll::Ready(Ok(0))
30    }
31}
32
33impl AsyncBufRead for Empty {
34    fn poll_fill_buf(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<&[u8]>> {
35        Poll::Ready(Ok(&[]))
36    }
37
38    fn consume(self: Pin<&mut Self>, _: usize) {}
39}
40
41impl AsyncWrite for Empty {
42    fn poll_write(
43        self: Pin<&mut Self>,
44        _: &mut Context<'_>,
45        buf: &[u8],
46    ) -> Poll<io::Result<usize>> {
47        Poll::Ready(Ok(buf.len()))
48    }
49
50    fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
51        Poll::Ready(Ok(()))
52    }
53
54    fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
55        Poll::Ready(Ok(()))
56    }
57}
58
59/// A reader that gives one byte over and over, without end. Made by
60/// [`repeat`].
61#[derive(Clone, Copy, Debug)]
62pub struct Repeat {
63    byte: u8,
64}
65
66/// A reader that gives `byte` over and over, without end.
67pub fn repeat(byte: u8) -> Repeat {
68    Repeat { byte }
69}
70
71impl AsyncRead for Repeat {
72    fn poll_read(
73        self: Pin<&mut Self>,
74        cx: &mut Context<'_>,
75        buf: &mut [u8],
76    ) -> Poll<io::Result<usize>> {
77        // Ready every time: it spends the task's budget, as IO does, so a
78        // loop over it yields to the other tasks.
79        crate::coop::poll_budget(cx, |_| {
80            buf.fill(self.byte);
81            Poll::Ready(Ok(buf.len()))
82        })
83    }
84}
85
86/// A writer that takes every byte and keeps none. Made by [`sink`].
87#[derive(Clone, Copy, Debug, Default)]
88pub struct Sink {
89    _private: (),
90}
91
92/// A writer that takes every byte and keeps none.
93pub fn sink() -> Sink {
94    Sink { _private: () }
95}
96
97impl AsyncWrite for Sink {
98    fn poll_write(
99        self: Pin<&mut Self>,
100        cx: &mut Context<'_>,
101        buf: &[u8],
102    ) -> Poll<io::Result<usize>> {
103        crate::coop::poll_budget(cx, |_| Poll::Ready(Ok(buf.len())))
104    }
105
106    fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
107        Poll::Ready(Ok(()))
108    }
109
110    fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
111        Poll::Ready(Ok(()))
112    }
113}