use alloc::vec::Vec;
use core::{
cmp, fmt,
fmt::{Display, Formatter},
mem,
};
pub trait Write {
fn write(&mut self, buf: &[u8]) -> Result<usize, Error>;
fn flush(&mut self) -> Result<(), Error>;
fn write_all(&mut self, mut buf: &[u8]) -> Result<(), Error> {
while !buf.is_empty() {
match self.write(buf) {
Ok(0) => {
return Err(ErrorKind::WriteZero.into());
}
Ok(n) => buf = &buf[n..],
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
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, Error> {
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 flush(&mut self) -> Result<(), Error> {
Ok(())
}
#[inline]
fn write_all(&mut self, data: &[u8]) -> Result<(), Error> {
if self.write(data)? == data.len() {
Ok(())
} else {
Err(ErrorKind::WriteZero.into())
}
}
}
impl Write for Vec<u8> {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
self.extend_from_slice(buf);
Ok(buf.len())
}
#[inline]
fn flush(&mut self) -> Result<(), Error> {
Ok(())
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> Result<(), Error> {
self.extend_from_slice(buf);
Ok(())
}
}
impl<W: Write + ?Sized> Write for &mut W {
fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
(**self).write(buf)
}
fn flush(&mut self) -> Result<(), Error> {
(**self).flush()
}
fn write_all(&mut self, buf: &[u8]) -> Result<(), Error> {
(**self).write_all(buf)
}
}
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
}
impl Error {
pub fn kind(&self) -> ErrorKind {
self.kind
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("{:?}", self.kind))
}
}
impl From<ErrorKind> for Error {
fn from(value: ErrorKind) -> Self {
Self { kind: value }
}
}
impl From<enough::StopReason> for Error {
fn from(_: enough::StopReason) -> Self {
Self {
kind: ErrorKind::Cancelled,
}
}
}
impl core::error::Error for Error {}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[non_exhaustive]
pub enum ErrorKind {
Interrupted,
WriteZero,
Cancelled,
Other,
}