use crate::{IoError, IoErrorKind, IoResult, Mem};
use ::core::{cmp, fmt};
#[doc = crate::_tags!(io)]
#[rustfmt::skip]
pub trait IoWrite {
fn write(&mut self, buf: &[u8]) -> IoResult<usize>;
fn flush(&mut self) -> IoResult<()>;
fn write_all(&mut self, mut buf: &[u8]) -> IoResult<()> {
while !buf.is_empty() {
match self.write(buf) {
Ok(0) => { return Err(IoError::new(
IoErrorKind::WriteZero, "failed to write whole buffer")); }
Ok(n) => buf = &buf[n..],
Err(ref e) if e.kind() == IoErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> IoResult<()> {
struct Adaptor<'a, T: ?Sized + 'a> {
inner: &'a mut T,
error: IoResult<()>,
}
impl<T: IoWrite + ?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(IoError::new(IoErrorKind::Other, "formatter error")) }
}
}
}
fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
}
impl<W: IoWrite + ?Sized> IoWrite for &mut W {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
(**self).write(buf)
}
fn flush(&mut self) -> IoResult<()> {
(**self).flush()
}
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
(**self).write_all(buf)
}
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> IoResult<()> {
(**self).write_fmt(fmt)
}
}
#[cfg(feature = "alloc")]
impl IoWrite for crate::Vec<u8> {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
self.extend_from_slice(buf);
Ok(buf.len())
}
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
self.extend_from_slice(buf);
Ok(())
}
fn flush(&mut self) -> IoResult<()> {
Ok(())
}
}
impl IoWrite for &mut [u8] {
fn write(&mut self, data: &[u8]) -> IoResult<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)
}
fn write_all(&mut self, data: &[u8]) -> IoResult<()> {
if self.write(data)? == data.len() {
Ok(())
} else {
Err(IoError::new(IoErrorKind::WriteZero, "failed to write whole buffer"))
}
}
fn flush(&mut self) -> IoResult<()> {
Ok(())
}
}