mod test;
use crate::io::{Bytes, ErrorKind, Result};
#[cfg(feature = "alloc")]
use crate::io::DEFAULT_BUF_SIZE;
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::fs::File;
#[cfg(feature = "std")]
use std::io::{BufReader, PipeReader, Stdin, StdinLock};
#[cfg(feature = "std")]
use std::net::TcpStream;
#[cfg(all(feature = "std", target_family = "unix"))]
use std::os::unix::net::UnixStream;
#[cfg(feature = "std")]
use std::process::{ChildStderr, ChildStdout};
#[cfg(all(feature = "std", target_has_atomic = "ptr"))]
use alloc::sync::Arc;
pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<()> {
while !buf.is_empty() {
match self.read(buf) {
Ok(0) => break,
Ok(count) => {
buf = &mut buf[count..];
}
Err(ref e) if e.is_interrupted() => {}
Err(e) => return Err(e),
}
}
Ok(())
}
#[cfg(feature = "alloc")]
#[inline]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
read_to_end_with(self, buf, |_| Ok(()))
}
#[cfg(feature = "alloc")]
#[inline]
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
let buf = unsafe { buf.as_mut_vec() };
read_to_end_with(
self,
buf,
|data| str::from_utf8(data).map(|_| ()).map_err(|_| ErrorKind::InvalidData.into()),
)
}
#[inline]
fn read_array<const N: usize>(&mut self) -> Result<[u8; N]>
where
Self: Sized,
{
let mut buf = [0; _];
self.read(&mut buf)?;
Ok(buf)
}
#[inline]
fn bytes(self) -> Bytes<Self>
where
Self: Sized,
{
Bytes::new(self)
}
#[inline(always)]
#[must_use]
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
}
#[cfg(all(feature = "std", target_has_atomic = "ptr"))]
impl Read for Arc<File> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "alloc")]
impl<R: ?Sized + Read> Read for Box<R> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = R::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
R::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl<R: ?Sized + std::io::Read> Read for BufReader<R> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for ChildStderr {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for ChildStdout {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl<T: AsRef<[u8]>> Read for std::io::Cursor<T> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for std::io::Empty {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for File {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for &File {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for PipeReader {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for &PipeReader {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
impl<R: Read> Read for &mut R {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
R::read(self, buf)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
R::read_exact(self, buf)
}
}
impl Read for &[u8] {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = buf.len().min(self.len());
let (slot, remainder) = self.split_at(count);
let buf = &mut buf[..count];
buf.copy_from_slice(slot);
*self = remainder;
Ok(count)
}
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
let count = buf.len();
let Some((slot, remainder)) = self.split_at_checked(count) else {
return Err(ErrorKind::WriteZero.into());
};
let buf = &mut buf[..count];
buf.copy_from_slice(slot);
*self = remainder;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for Stdin {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for &Stdin {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for StdinLock<'_> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for TcpStream {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "std")]
impl Read for &TcpStream {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(all(feature = "std", target_family = "unix"))]
impl Read for UnixStream {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let count = std::io::Read::read(self, buf)?;
Ok(count)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
std::io::Read::read_exact(self, buf)?;
Ok(())
}
}
#[cfg(feature = "alloc")]
pub fn read_to_string<R: Read>(mut r: R) -> Result<String> {
let mut buf = String::new();
r.read_to_string(&mut buf)?;
Ok(buf)
}
#[cfg(feature = "alloc")]
fn read_to_end_with<R: ?Sized + Read, F: FnMut(&[u8]) -> Result<()>>(r: &mut R, buf: &mut Vec<u8>, mut f: F) -> Result<usize> {
let start_len = buf.len();
const PROBE_SIZE: usize = 32;
let mut tmp = [0; PROBE_SIZE];
loop {
match r.read(&mut tmp) {
Ok(count) => {
let tmp = &tmp[..count];
f(tmp)?;
buf.extend_from_slice(tmp);
break;
}
Err(ref e) if e.is_interrupted() => {}
Err(e) => {
return Err(e);
}
}
}
let mut tmp = [0; DEFAULT_BUF_SIZE];
loop {
match r.read(&mut tmp) {
Ok(0) => {
let count = buf.len() - start_len;
break Ok(count);
}
Ok(count) => {
let tmp = &tmp[..count];
f(tmp)?;
buf.extend_from_slice(tmp);
}
Err(ref e) if e.is_interrupted() => {}
Err(e) => {
break Err(e);
}
}
}
}