use std::io;
#[cfg(unix)]
pub trait FileExt {
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
#[cfg(unix_file_vectored_at)]
fn read_vectored_at(&self, bufs: &mut [io::IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
default_read_vectored(|b| self.read_at(b, offset), bufs)
}
fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> {
while !buf.is_empty() {
match self.read_at(buf, offset) {
Ok(0) => break,
Ok(n) => {
let tmp = buf;
buf = &mut tmp[n..];
offset += n as u64;
}
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
if !buf.is_empty() {
Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
"failed to fill whole buffer",
))
} else {
Ok(())
}
}
fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
#[cfg(unix_file_vectored_at)]
fn write_vectored_at(&self, bufs: &[io::IoSlice<'_>], offset: u64) -> io::Result<usize> {
default_write_vectored(|b| self.write_at(b, offset), bufs)
}
fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
while !buf.is_empty() {
match self.write_at(buf, offset) {
Ok(0) => {
return Err(io::Error::new(
io::ErrorKind::WriteZero,
"failed to write whole buffer",
));
}
Ok(n) => {
buf = &buf[n..];
offset += n as u64
}
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
}
#[cfg(unix_file_vectored_at)]
fn default_read_vectored<F>(read: F, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize>
where
F: FnOnce(&mut [u8]) -> io::Result<usize>,
{
let buf = bufs
.iter_mut()
.find(|b| !b.is_empty())
.map_or(&mut [][..], |b| &mut **b);
read(buf)
}
#[cfg(unix_file_vectored_at)]
fn default_write_vectored<F>(write: F, bufs: &[io::IoSlice<'_>]) -> io::Result<usize>
where
F: FnOnce(&[u8]) -> io::Result<usize>,
{
let buf = bufs
.iter()
.find(|b| !b.is_empty())
.map_or(&[][..], |b| &**b);
write(buf)
}
#[cfg(target_os = "wasi")]
pub trait FileExt {
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
let bufs = &mut [io::IoSliceMut::new(buf)];
self.read_vectored_at(bufs, offset)
}
fn read_vectored_at(&self, bufs: &mut [io::IoSliceMut<'_>], offset: u64) -> io::Result<usize>;
fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> {
while !buf.is_empty() {
match self.read_at(buf, offset) {
Ok(0) => break,
Ok(n) => {
let tmp = buf;
buf = &mut tmp[n..];
offset += n as u64;
}
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
if !buf.is_empty() {
Err(io::Error::new(
io::ErrorKind::UnexpectedEof,
"failed to fill whole buffer",
))
} else {
Ok(())
}
}
fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
let bufs = &[io::IoSlice::new(buf)];
self.write_vectored_at(bufs, offset)
}
fn write_vectored_at(&self, bufs: &[io::IoSlice<'_>], offset: u64) -> io::Result<usize>;
fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
while !buf.is_empty() {
match self.write_at(buf, offset) {
Ok(0) => {
return Err(io::Error::new(
io::ErrorKind::WriteZero,
"failed to write whole buffer",
));
}
Ok(n) => {
buf = &buf[n..];
offset += n as u64
}
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
fn tell(&self) -> io::Result<u64>;
fn fdstat_set_flags(&self, flags: u16) -> io::Result<()>;
fn fdstat_set_rights(&self, rights: u64, inheriting: u64) -> io::Result<()>;
fn advise(&self, offset: u64, len: u64, advice: u8) -> io::Result<()>;
fn allocate(&self, offset: u64, len: u64) -> io::Result<()>;
fn create_directory<P: AsRef<std::path::Path>>(&self, dir: P) -> io::Result<()>;
fn read_link<P: AsRef<std::path::Path>>(&self, path: P) -> io::Result<std::path::PathBuf>;
fn metadata_at<P: AsRef<std::path::Path>>(
&self,
lookup_flags: u32,
path: P,
) -> io::Result<std::fs::Metadata>;
fn remove_file<P: AsRef<std::path::Path>>(&self, path: P) -> io::Result<()>;
fn remove_directory<P: AsRef<std::path::Path>>(&self, path: P) -> io::Result<()>;
}
#[cfg(windows)]
pub trait FileExt {
fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
}