use std::fs::File;
use std::io::{
self, BufRead, BufReader, Chain, Cursor, Empty, Read, Repeat, Seek, SeekFrom, StdinLock, Take,
};
use std::net::TcpStream;
#[cfg(unix)]
use std::os::unix::net::UnixStream;
pub trait Peek {
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize>;
}
impl Peek for File {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let pos = self.seek(SeekFrom::Current(0))?;
crate::fs::FileIoExt::read_at(self, buf, pos)
}
}
#[cfg(feature = "cap_std_impls")]
impl Peek for cap_std::fs::File {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let pos = self.seek(SeekFrom::Current(0))?;
crate::fs::FileIoExt::read_at(self, buf, pos)
}
}
#[cfg(feature = "cap_std_impls_fs_utf8")]
impl Peek for cap_std::fs_utf8::File {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let pos = self.seek(SeekFrom::Current(0))?;
crate::fs::FileIoExt::read_at(self, buf, pos)
}
}
impl Peek for TcpStream {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
TcpStream::peek(self, buf)
}
}
#[cfg(unix)]
impl Peek for UnixStream {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
#[cfg(unix_socket_peek)]
{
UnixStream::peek(self, buf)
}
#[cfg(not(unix_socket_peek))]
{
let _ = buf;
Ok(0)
}
}
}
impl Peek for Repeat {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.read(buf)
}
}
#[cfg(feature = "socketpair")]
impl Peek for socketpair::SocketpairStream {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
socketpair::SocketpairStream::peek(self, buf)
}
}
impl Peek for Empty {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
peek_from_bufread(self, buf)
}
}
impl<'a> Peek for &'a [u8] {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
peek_from_bufread(self, buf)
}
}
impl<'a> Peek for StdinLock<'a> {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
peek_from_bufread(self, buf)
}
}
impl<B: BufRead + ?Sized> Peek for Box<B> {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
peek_from_bufread(self, buf)
}
}
impl<'a, B: BufRead + ?Sized> Peek for &'a mut B {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
peek_from_bufread(self, buf)
}
}
impl<R: Read> Peek for BufReader<R> {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
peek_from_bufread(self, buf)
}
}
impl<T> Peek for Cursor<T>
where
T: AsRef<[u8]>,
{
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
peek_from_bufread(self, buf)
}
}
impl<T: BufRead> Peek for Take<T> {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
peek_from_bufread(self, buf)
}
}
impl<T: BufRead, U: BufRead> Peek for Chain<T, U> {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
peek_from_bufread(self, buf)
}
}
#[inline]
pub fn peek_from_bufread<BR: BufRead>(buf_read: &mut BR, buf: &mut [u8]) -> io::Result<usize> {
Read::read(&mut buf_read.fill_buf()?, buf)
}
#[cfg(feature = "socket2")]
impl Peek for socket2::Socket {
#[inline]
fn peek(&mut self, buf: &mut [u8]) -> io::Result<usize> {
use io_lifetimes::AsSocketlike;
self.as_socketlike_view::<std::net::TcpStream>().peek(buf)
}
}