use alloc::string::String;
use alloc::vec::Vec;
use core::{fmt, result};
#[allow(clippy::upper_case_acronyms)]
#[derive(Debug, PartialEq, FromPrimitive, ToPrimitive)]
pub enum Error {
ENOENT = crate::errno::ENOENT as isize,
ENOSYS = crate::errno::ENOSYS as isize,
EIO = crate::errno::EIO as isize,
EBADF = crate::errno::EBADF as isize,
EISDIR = crate::errno::EISDIR as isize,
EINVAL = crate::errno::EINVAL as isize,
ETIME = crate::errno::ETIME as isize,
EAGAIN = crate::errno::EAGAIN as isize,
EFAULT = crate::errno::EFAULT as isize,
ENOBUFS = crate::errno::ENOBUFS as isize,
ENOTCONN = crate::errno::ENOTCONN as isize,
ENOTDIR = crate::errno::ENOTDIR as isize,
EMFILE = crate::errno::EMFILE as isize,
EEXIST = crate::errno::EEXIST as isize,
EADDRINUSE = crate::errno::EADDRINUSE as isize,
EOVERFLOW = crate::errno::EOVERFLOW as isize,
ENOTSOCK = crate::errno::ENOTSOCK as isize,
}
pub type Result<T> = result::Result<T, Error>;
pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
let start_len = buf.len();
loop {
let mut probe = [0u8; 512];
match self.read(&mut probe) {
Ok(0) => return Ok(buf.len() - start_len),
Ok(n) => {
buf.extend_from_slice(&probe[..n]);
}
Err(e) => return Err(e),
}
}
}
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {
unsafe { self.read_to_end(buf.as_mut_vec()) }
}
}
pub trait Write {
fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
while !buf.is_empty() {
match self.write(buf) {
Ok(0) => {
return Err(Error::EIO);
}
Ok(n) => buf = &buf[n..],
Err(e) => return Err(e),
}
}
Ok(())
}
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> {
struct Adapter<'a, T: ?Sized> {
inner: &'a mut T,
error: Result<()>,
}
impl<T: Write + ?Sized> fmt::Write for Adapter<'_, 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 = Adapter {
inner: self,
error: Ok(()),
};
match fmt::write(&mut output, fmt) {
Ok(()) => Ok(()),
Err(..) => {
if output.error.is_err() {
output.error
} else {
Err(Error::EINVAL)
}
}
}
}
}