use crate::{Error, ErrorKind, Result};
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)? {
0 => break,
n => {
let tmp = buf;
buf = &mut tmp[n..];
}
}
}
if !buf.is_empty() {
Err(Error::from_kind(ErrorKind::FailedToFillTheWholeBuffer))
} else {
Ok(())
}
}
}
pub trait BufRead: Read {
fn fill_buf(&mut self) -> Result<&[u8]>;
fn consume(&mut self, amt: usize);
}
pub trait Write {
fn write_all(&mut self, buf: &[u8]) -> Result<()>;
}
#[cfg(feature = "std")]
mod std_impls {
use crate::io::{BufRead, Read, Write};
use crate::Result;
impl<R> Read for R
where
R: std::io::Read,
{
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
loop {
match std::io::Read::read(self, buf) {
Ok(n) => return Ok(n),
Err(e) if e.kind() == std::io::ErrorKind::Interrupted => {}
Err(e) => return Err(e.into()),
}
}
}
}
impl<R> BufRead for R
where
R: std::io::BufRead,
{
fn fill_buf(&mut self) -> Result<&[u8]> {
Ok(std::io::BufRead::fill_buf(self)?)
}
fn consume(&mut self, amt: usize) {
std::io::BufRead::consume(self, amt)
}
}
impl<W> Write for W
where
W: std::io::Write,
{
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
std::io::Write::write_all(self, buf)?;
Ok(())
}
}
}
#[cfg(all(feature = "embedded-io", not(feature = "std")))]
mod embedded_io_impls {
use crate::io::{BufRead, Read, Write};
use crate::Result;
use embedded_io::Error;
impl<W: embedded_io::Write> Write for W {
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
embedded_io::Write::write_all(self, buf)
.map_err(|e| crate::Error::from_kind(e.kind().into()))?;
Ok(())
}
}
impl<R: embedded_io::Read> Read for R {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
embedded_io::Read::read(self, buf).map_err(|e| crate::Error::from_kind(e.kind().into()))
}
}
impl<R: embedded_io::BufRead + embedded_io::Read> BufRead for R {
fn fill_buf(&mut self) -> Result<&[u8]> {
embedded_io::BufRead::fill_buf(self)
.map_err(|e| crate::Error::from_kind(e.kind().into()))
}
fn consume(&mut self, amt: usize) {
embedded_io::BufRead::consume(self, amt)
}
}
}
#[cfg(not(any(feature = "std", feature = "embedded-io")))]
mod no_std_impls {
use crate::io::{BufRead, Read, Write};
use crate::{Error, ErrorKind, Result};
impl<'a> Write for &'a mut [u8] {
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
if buf.len() > self.len() {
return Err(Error::from_kind(ErrorKind::BufferNotLargeEnough));
}
let amt = buf.len();
let (a, b) = core::mem::take(self).split_at_mut(amt);
a.copy_from_slice(buf);
*self = b;
Ok(())
}
}
#[cfg(feature = "alloc")]
impl Write for alloc::vec::Vec<u8> {
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
self.extend_from_slice(buf);
Ok(())
}
}
impl<W: ?Sized> Write for &mut W
where
W: Write,
{
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
(**self).write_all(buf)
}
}
impl<'a> Read for &'a [u8] {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
let amt = core::cmp::min(buf.len(), self.len());
let (a, b) = self.split_at(amt);
buf[..amt].copy_from_slice(a);
*self = b;
Ok(amt)
}
}
impl<R: ?Sized> Read for &mut R
where
R: Read,
{
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
(**self).read(buf)
}
}
impl<'a> BufRead for &'a [u8] {
fn fill_buf(&mut self) -> Result<&[u8]> {
Ok(*self)
}
fn consume(&mut self, amt: usize) {
*self = &self[amt..]
}
}
impl<R: ?Sized> BufRead for &mut R
where
R: BufRead,
{
fn fill_buf(&mut self) -> Result<&[u8]> {
(**self).fill_buf()
}
fn consume(&mut self, amt: usize) {
(**self).consume(amt)
}
}
}