#![cfg(not(feature = "std"))]
use core::fmt;
use crate::{BufRead, ErrorKind, IoSlice, IoSliceMut, Read, Result, Seek, SeekFrom, Write};
#[non_exhaustive]
#[derive(Copy, Clone, Default)]
pub struct Empty;
#[must_use]
pub const fn empty() -> Empty {
Empty
}
impl Read for Empty {
#[inline]
fn read(&mut self, _buf: &mut [u8]) -> Result<usize> {
Ok(0)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, Some(0))
}
}
impl BufRead for Empty {
#[inline]
fn fill_buf(&mut self) -> Result<&[u8]> {
Ok(&[])
}
#[inline]
fn consume(&mut self, _n: usize) {}
}
impl Seek for Empty {
fn seek(&mut self, _pos: SeekFrom) -> Result<u64> {
Ok(0)
}
fn stream_len(&mut self) -> Result<u64> {
Ok(0)
}
fn stream_position(&mut self) -> Result<u64> {
Ok(0)
}
}
impl fmt::Debug for Empty {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Empty").finish_non_exhaustive()
}
}
pub struct Repeat {
byte: u8,
}
#[must_use]
pub const fn repeat(byte: u8) -> Repeat {
Repeat { byte }
}
impl Read for Repeat {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
for slot in &mut *buf {
*slot = self.byte;
}
Ok(buf.len())
}
#[inline]
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {
let mut nwritten = 0;
for buf in bufs {
nwritten += self.read(buf)?;
}
Ok(nwritten)
}
#[inline]
fn is_read_vectored(&self) -> bool {
true
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(usize::MAX, None)
}
}
impl fmt::Debug for Repeat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Repeat").finish_non_exhaustive()
}
}
#[non_exhaustive]
#[derive(Copy, Clone, Default)]
pub struct Sink;
#[must_use]
pub const fn sink() -> Sink {
Sink
}
impl Write for Sink {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize> {
Ok(buf.len())
}
#[inline]
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
let total_len = bufs.iter().map(|b| b.len()).sum();
Ok(total_len)
}
#[inline]
fn is_write_vectored(&self) -> bool {
true
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
impl Write for &Sink {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize> {
Ok(buf.len())
}
#[inline]
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {
let total_len = bufs.iter().map(|b| b.len()).sum();
Ok(total_len)
}
#[inline]
fn is_write_vectored(&self) -> bool {
true
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
impl fmt::Debug for Sink {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Sink").finish_non_exhaustive()
}
}
pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64>
where
R: Read,
W: Write,
{
stack_buffer_copy(reader, writer)
}
pub(crate) fn stack_buffer_copy<R: Read + ?Sized, W: Write + ?Sized>(
reader: &mut R,
writer: &mut W,
) -> Result<u64> {
let mut buf = [0u8; crate::DEFAULT_BUF_SIZE];
let mut written = 0;
loop {
let len = match reader.read(&mut buf) {
Ok(0) => return Ok(written),
Ok(len) => len,
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e),
};
writer.write_all(&buf[..len])?;
written += len as u64;
}
}