#![allow(clippy::pedantic)]
mod cursor;
mod error;
use alloc::{string::String, vec::Vec};
use core::{cmp, fmt, mem};
pub use {
cursor::Cursor,
error::{Error, ErrorKind},
};
pub type Result<T> = core::result::Result<T, Error>;
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(n) => {
let tmp = buf;
buf = &mut tmp[n..];
}
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
if !buf.is_empty() {
Err(Error::new(
ErrorKind::UnexpectedEof,
"failed to fill whole buffer",
))
} else {
Ok(())
}
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
let mut tmp = [0; 32];
let mut amt = 0;
loop {
match self.read(&mut tmp) {
Ok(0) => break Ok(amt),
Ok(n) => {
amt += n;
buf.extend_from_slice(&tmp[..n]);
}
Err(err) if err.kind() == ErrorKind::Interrupted => continue,
err @ Err(_) => return err,
}
}
}
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
let mut tmp = Vec::new();
let amt = self.read_to_end(&mut tmp)?;
let str = core::str::from_utf8(&tmp).map_err(|_| {
Error::new(ErrorKind::InvalidData, "stream did not contain valid UTF-8")
})?;
buf.push_str(str);
Ok(amt)
}
fn bytes(self) -> Bytes<Self>
where
Self: Sized,
{
Bytes { inner: self }
}
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
fn take(self, limit: u64) -> Take<Self>
where
Self: Sized,
{
Take { inner: self, limit }
}
}
#[derive(Debug)]
pub struct Take<T> {
inner: T,
limit: u64,
}
impl<T> Take<T> {
pub fn limit(&self) -> u64 {
self.limit
}
pub fn set_limit(&mut self, limit: u64) {
self.limit = limit;
}
pub fn into_inner(self) -> T {
self.inner
}
pub fn get_ref(&self) -> &T {
&self.inner
}
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
}
impl<T: Read> Read for Take<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
if self.limit == 0 {
return Ok(0);
}
let max = core::cmp::min(buf.len() as u64, self.limit) as usize;
let n = self.inner.read(&mut buf[..max])?;
self.limit -= n as u64;
Ok(n)
}
}
impl<R: Read + ?Sized> Read for &mut R {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
(**self).read(buf)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
(**self).read_exact(buf)
}
}
#[derive(Debug)]
pub struct Bytes<R: Read> {
inner: R,
}
impl<R: Read> Iterator for Bytes<R> {
type Item = Result<u8>;
fn next(&mut self) -> Option<Result<u8>> {
let mut byte = 0;
loop {
return match self.inner.read(core::slice::from_mut(&mut byte)) {
Ok(0) => None,
Ok(..) => Some(Ok(byte)),
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => Some(Err(e)),
};
}
}
}
impl Read for &[u8] {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let amt = cmp::min(buf.len(), self.len());
let (a, b) = self.split_at(amt);
if amt == 1 {
buf[0] = a[0];
} else {
buf[..amt].copy_from_slice(a);
}
*self = b;
Ok(amt)
}
#[inline]
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
if buf.len() > self.len() {
return Err(Error::new(
ErrorKind::UnexpectedEof,
"failed to fill whole buffer",
));
}
let (a, b) = self.split_at(buf.len());
if buf.len() == 1 {
buf[0] = a[0];
} else {
buf.copy_from_slice(a);
}
*self = b;
Ok(())
}
#[inline]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
buf.extend_from_slice(self);
let len = self.len();
*self = &self[len..];
Ok(len)
}
}
#[derive(Debug, Clone, Copy)]
pub enum SeekFrom {
Start(u64),
End(i64),
Current(i64),
}
pub trait Seek {
fn seek(&mut self, pos: SeekFrom) -> Result<u64>;
fn stream_position(&mut self) -> Result<u64> {
self.seek(SeekFrom::Current(0))
}
}
impl<S: Seek + ?Sized> Seek for &mut S {
#[inline]
fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
(**self).seek(pos)
}
}
pub trait Write {
fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn flush(&mut self) -> Result<()>;
fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
while !buf.is_empty() {
match self.write(buf) {
Ok(0) => {
return Err(Error::new(
ErrorKind::WriteZero,
"failed to write whole buffer",
));
}
Ok(n) => buf = &buf[n..],
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> {
struct Adaptor<'a, T: ?Sized> {
inner: &'a mut T,
error: Result<()>,
}
impl<T: Write + ?Sized> fmt::Write for Adaptor<'_, T> {
fn write_str(&mut self, s: &str) -> fmt::Result {
match self.inner.write_all(s.as_bytes()) {
Ok(()) => Ok(()),
Err(e) => {
self.error = Err(e);
Err(fmt::Error)
}
}
}
}
let mut output = Adaptor {
inner: self,
error: Ok(()),
};
match fmt::write(&mut output, fmt) {
Ok(()) => Ok(()),
Err(..) => {
if output.error.is_err() {
output.error
} else {
Err(Error::new(ErrorKind::Other, "formatter error"))
}
}
}
}
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
}
impl Write for &mut [u8] {
#[inline]
fn write(&mut self, data: &[u8]) -> Result<usize> {
let amt = cmp::min(data.len(), self.len());
let (a, b) = mem::take(self).split_at_mut(amt);
a.copy_from_slice(&data[..amt]);
*self = b;
Ok(amt)
}
#[inline]
fn write_all(&mut self, data: &[u8]) -> Result<()> {
if self.write(data)? == data.len() {
Ok(())
} else {
Err(Error::new(
ErrorKind::WriteZero,
&"failed to write whole buffer",
))
}
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
impl Write for Vec<u8> {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.extend_from_slice(buf);
Ok(buf.len())
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
self.extend_from_slice(buf);
Ok(())
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}