blob: ab9259611822615bda594b6a04bfcd5ae155e33b [file] [log] [blame]
use std::pin::Pin;
use crate::io::{self, Read};
use crate::stream::stream::Stream;
use crate::task::{Context, Poll};
/// A stream over `u8` values of a reader.
///
/// This struct is generally created by calling [`bytes`] on a reader.
/// Please see the documentation of [`bytes`] for more details.
///
/// [`bytes`]: trait.Read.html#method.bytes
#[derive(Debug)]
pub struct Bytes<T> {
pub(crate) inner: T,
}
impl<T: Read + Unpin> Stream for Bytes<T> {
type Item = io::Result<u8>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let mut byte = 0;
let rd = Pin::new(&mut self.inner);
match futures_core::ready!(rd.poll_read(cx, std::slice::from_mut(&mut byte))) {
Ok(0) => Poll::Ready(None),
Ok(..) => Poll::Ready(Some(Ok(byte))),
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => Poll::Pending,
Err(e) => Poll::Ready(Some(Err(e))),
}
}
}
#[cfg(all(test, default))]
mod tests {
use crate::io;
use crate::prelude::*;
use crate::task;
#[test]
fn test_bytes_basics() -> std::io::Result<()> {
task::block_on(async move {
let raw: Vec<u8> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8];
let source: io::Cursor<Vec<u8>> = io::Cursor::new(raw.clone());
let mut s = source.bytes();
// TODO(@dignifiedquire): Use collect, once it is stable.
let mut result = Vec::new();
while let Some(byte) = s.next().await {
result.push(byte?);
}
assert_eq!(result, raw);
Ok(())
})
}
}