From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/fs-err/src/dir.rs | 85 +++++++++++ vendor/fs-err/src/errors.rs | 204 +++++++++++++++++++++++++ vendor/fs-err/src/file.rs | 310 ++++++++++++++++++++++++++++++++++++++ vendor/fs-err/src/lib.rs | 246 ++++++++++++++++++++++++++++++ vendor/fs-err/src/open_options.rs | 133 ++++++++++++++++ vendor/fs-err/src/os.rs | 11 ++ vendor/fs-err/src/os/unix.rs | 38 +++++ vendor/fs-err/src/os/windows.rs | 49 ++++++ vendor/fs-err/src/path.rs | 43 ++++++ 9 files changed, 1119 insertions(+) create mode 100644 vendor/fs-err/src/dir.rs create mode 100644 vendor/fs-err/src/errors.rs create mode 100644 vendor/fs-err/src/file.rs create mode 100644 vendor/fs-err/src/lib.rs create mode 100644 vendor/fs-err/src/open_options.rs create mode 100644 vendor/fs-err/src/os.rs create mode 100644 vendor/fs-err/src/os/unix.rs create mode 100644 vendor/fs-err/src/os/windows.rs create mode 100644 vendor/fs-err/src/path.rs (limited to 'vendor/fs-err/src') diff --git a/vendor/fs-err/src/dir.rs b/vendor/fs-err/src/dir.rs new file mode 100644 index 000000000..adba643b9 --- /dev/null +++ b/vendor/fs-err/src/dir.rs @@ -0,0 +1,85 @@ +use std::ffi::OsString; +use std::fs; +use std::io; +use std::path::PathBuf; + +use crate::errors::{Error, ErrorKind}; + +/// Wrapper for [`fs::read_dir`](https://doc.rust-lang.org/stable/std/fs/fn.read_dir.html). +pub fn read_dir>(path: P) -> io::Result { + let path = path.into(); + + match fs::read_dir(&path) { + Ok(inner) => Ok(ReadDir { inner, path }), + Err(source) => Err(Error::new(source, ErrorKind::ReadDir, path)), + } +} + +/// Wrapper around [`std::fs::ReadDir`][std::fs::ReadDir] which adds more +/// helpful information to all errors. +/// +/// This struct is created via [`fs_err::read_dir`][fs_err::read_dir]. +/// +/// [std::fs::ReadDir]: https://doc.rust-lang.org/stable/std/fs/struct.ReadDir.html +/// [fs_err::read_dir]: fn.read_dir.html +#[derive(Debug)] +pub struct ReadDir { + inner: fs::ReadDir, + path: PathBuf, +} + +impl Iterator for ReadDir { + type Item = io::Result; + + fn next(&mut self) -> Option { + Some(self.inner.next()?.map(|inner| DirEntry { inner })) + } +} + +/// Wrapper around [`std::fs::DirEntry`][std::fs::DirEntry] which adds more +/// helpful information to all errors. +/// +/// [std::fs::DirEntry]: https://doc.rust-lang.org/stable/std/fs/struct.DirEntry.html +#[derive(Debug)] +pub struct DirEntry { + inner: fs::DirEntry, +} + +impl DirEntry { + /// Wrapper for [`DirEntry::path`](https://doc.rust-lang.org/stable/std/fs/struct.DirEntry.html#method.path). + pub fn path(&self) -> PathBuf { + self.inner.path() + } + + /// Wrapper for [`DirEntry::metadata`](https://doc.rust-lang.org/stable/std/fs/struct.DirEntry.html#method.metadata). + pub fn metadata(&self) -> io::Result { + self.inner + .metadata() + .map_err(|source| Error::new(source, ErrorKind::Metadata, self.path())) + } + + /// Wrapper for [`DirEntry::file_type`](https://doc.rust-lang.org/stable/std/fs/struct.DirEntry.html#method.file_type). + pub fn file_type(&self) -> io::Result { + self.inner + .file_type() + .map_err(|source| Error::new(source, ErrorKind::Metadata, self.path())) + } + + /// Wrapper for [`DirEntry::file_name`](https://doc.rust-lang.org/stable/std/fs/struct.DirEntry.html#method.file_name). + pub fn file_name(&self) -> OsString { + self.inner.file_name() + } +} + +#[cfg(unix)] +mod unix { + use std::os::unix::fs::DirEntryExt; + + use super::*; + + impl DirEntryExt for DirEntry { + fn ino(&self) -> u64 { + self.inner.ino() + } + } +} diff --git a/vendor/fs-err/src/errors.rs b/vendor/fs-err/src/errors.rs new file mode 100644 index 000000000..466d28f11 --- /dev/null +++ b/vendor/fs-err/src/errors.rs @@ -0,0 +1,204 @@ +use std::error::Error as StdError; +use std::fmt; +use std::io; +use std::path::PathBuf; + +#[derive(Debug, Clone, Copy)] +pub(crate) enum ErrorKind { + OpenFile, + CreateFile, + CreateDir, + SyncFile, + SetLen, + Metadata, + Clone, + SetPermissions, + Read, + Seek, + Write, + Flush, + ReadDir, + RemoveFile, + RemoveDir, + Canonicalize, + ReadLink, + SymlinkMetadata, + + #[cfg(windows)] + SeekRead, + #[cfg(windows)] + SeekWrite, + + #[cfg(unix)] + ReadAt, + #[cfg(unix)] + WriteAt, +} + +/// Contains an IO error that has a file path attached. +/// +/// This type is never returned directly, but is instead wrapped inside yet +/// another IO error. +#[derive(Debug)] +pub(crate) struct Error { + kind: ErrorKind, + source: io::Error, + path: PathBuf, +} + +impl Error { + pub fn new(source: io::Error, kind: ErrorKind, path: impl Into) -> io::Error { + Self::_new(source, kind, path.into()) + } + + fn _new(source: io::Error, kind: ErrorKind, path: PathBuf) -> io::Error { + io::Error::new(source.kind(), Self { kind, source, path }) + } +} + +impl fmt::Display for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + use ErrorKind::*; + + let path = self.path.display(); + + match self.kind { + OpenFile => write!(formatter, "failed to open file `{}`", path), + CreateFile => write!(formatter, "failed to create file `{}`", path), + CreateDir => write!(formatter, "failed to create directory `{}`", path), + SyncFile => write!(formatter, "failed to sync file `{}`", path), + SetLen => write!(formatter, "failed to set length of file `{}`", path), + Metadata => write!(formatter, "failed to query metadata of file `{}`", path), + Clone => write!(formatter, "failed to clone handle for file `{}`", path), + SetPermissions => write!(formatter, "failed to set permissions for file `{}`", path), + Read => write!(formatter, "failed to read from file `{}`", path), + Seek => write!(formatter, "failed to seek in file `{}`", path), + Write => write!(formatter, "failed to write to file `{}`", path), + Flush => write!(formatter, "failed to flush file `{}`", path), + ReadDir => write!(formatter, "failed to read directory `{}`", path), + RemoveFile => write!(formatter, "failed to remove file `{}`", path), + RemoveDir => write!(formatter, "failed to remove directory `{}`", path), + Canonicalize => write!(formatter, "failed to canonicalize path `{}`", path), + ReadLink => write!(formatter, "failed to read symbolic link `{}`", path), + SymlinkMetadata => write!(formatter, "failed to query metadata of symlink `{}`", path), + + #[cfg(windows)] + SeekRead => write!(formatter, "failed to seek and read from `{}`", path), + #[cfg(windows)] + SeekWrite => write!(formatter, "failed to seek and write to `{}`", path), + + #[cfg(unix)] + ReadAt => write!(formatter, "failed to read with offset from `{}`", path), + #[cfg(unix)] + WriteAt => write!(formatter, "failed to write with offset to `{}`", path), + } + } +} + +impl StdError for Error { + fn cause(&self) -> Option<&dyn StdError> { + self.source() + } + + fn source(&self) -> Option<&(dyn StdError + 'static)> { + Some(&self.source) + } +} + +#[derive(Debug, Clone, Copy)] +pub(crate) enum SourceDestErrorKind { + Copy, + HardLink, + Rename, + SoftLink, + + #[cfg(unix)] + Symlink, + + #[cfg(windows)] + SymlinkDir, + #[cfg(windows)] + SymlinkFile, +} + +/// Error type used by functions like `fs::copy` that holds two paths. +#[derive(Debug)] +pub(crate) struct SourceDestError { + kind: SourceDestErrorKind, + source: io::Error, + from_path: PathBuf, + to_path: PathBuf, +} + +impl SourceDestError { + pub fn new( + source: io::Error, + kind: SourceDestErrorKind, + from_path: impl Into, + to_path: impl Into, + ) -> io::Error { + Self::_new(source, kind, from_path.into(), to_path.into()) + } + + fn _new( + source: io::Error, + kind: SourceDestErrorKind, + from_path: PathBuf, + to_path: PathBuf, + ) -> io::Error { + io::Error::new( + source.kind(), + Self { + kind, + source, + from_path, + to_path, + }, + ) + } +} + +impl fmt::Display for SourceDestError { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + let from = self.from_path.display(); + let to = self.to_path.display(); + match self.kind { + SourceDestErrorKind::Copy => { + write!(formatter, "failed to copy file from {} to {}", from, to) + } + SourceDestErrorKind::HardLink => { + write!(formatter, "failed to hardlink file from {} to {}", from, to) + } + SourceDestErrorKind::Rename => { + write!(formatter, "failed to rename file from {} to {}", from, to) + } + SourceDestErrorKind::SoftLink => { + write!(formatter, "failed to softlink file from {} to {}", from, to) + } + + #[cfg(unix)] + SourceDestErrorKind::Symlink => { + write!(formatter, "failed to symlink file from {} to {}", from, to) + } + + #[cfg(windows)] + SourceDestErrorKind::SymlinkFile => { + write!(formatter, "failed to symlink file from {} to {}", from, to) + } + #[cfg(windows)] + SourceDestErrorKind::SymlinkDir => { + write!(formatter, "failed to symlink dir from {} to {}", from, to) + } + } + } +} + +impl StdError for SourceDestError { + fn cause(&self) -> Option<&dyn StdError> { + self.source() + } + + fn source(&self) -> Option<&(dyn StdError + 'static)> { + Some(&self.source) + } +} diff --git a/vendor/fs-err/src/file.rs b/vendor/fs-err/src/file.rs new file mode 100644 index 000000000..a9c8988e5 --- /dev/null +++ b/vendor/fs-err/src/file.rs @@ -0,0 +1,310 @@ +use std::fs; +use std::io::{self, Read, Seek, Write}; +use std::path::{Path, PathBuf}; + +use crate::errors::{Error, ErrorKind}; + +/// Wrapper around [`std::fs::File`][std::fs::File] which adds more helpful +/// information to all errors. +/// +/// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html +#[derive(Debug)] +pub struct File { + file: fs::File, + path: PathBuf, +} + +// Opens a std File and returns it or an error generator which only needs the path to produce the error. +// Exists for the `crate::read*` functions so they don't unconditionally build a PathBuf. +pub(crate) fn open(path: &Path) -> Result io::Error> { + fs::File::open(&path).map_err(|err| |path| Error::new(err, ErrorKind::OpenFile, path)) +} + +// like `open()` but for `crate::write` +pub(crate) fn create(path: &Path) -> Result io::Error> { + fs::File::create(&path).map_err(|err| |path| Error::new(err, ErrorKind::CreateFile, path)) +} + +/// Wrappers for methods from [`std::fs::File`][std::fs::File]. +/// +/// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html +impl File { + /// Wrapper for [`File::open`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.open). + pub fn open

(path: P) -> Result + where + P: Into, + { + let path = path.into(); + match open(&path) { + Ok(file) => Ok(File::from_parts(file, path)), + Err(err_gen) => Err(err_gen(path)), + } + } + + /// Wrapper for [`File::create`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.create). + pub fn create

(path: P) -> Result + where + P: Into, + { + let path = path.into(); + match create(&path) { + Ok(file) => Ok(File::from_parts(file, path)), + Err(err_gen) => Err(err_gen(path)), + } + } + + /// Wrapper for [`OpenOptions::open`](https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html#method.open). + /// + /// This takes [`&std::fs::OpenOptions`](https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html), + /// not [`crate::OpenOptions`]. + #[deprecated = "use fs_err::OpenOptions::open instead"] + pub fn from_options

(path: P, options: &fs::OpenOptions) -> Result + where + P: Into, + { + let path = path.into(); + match options.open(&path) { + Ok(file) => Ok(File::from_parts(file, path)), + Err(source) => Err(Error::new(source, ErrorKind::OpenFile, path)), + } + } + + /// Wrapper for [`File::sync_all`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.sync_all). + pub fn sync_all(&self) -> Result<(), io::Error> { + self.file + .sync_all() + .map_err(|source| self.error(source, ErrorKind::SyncFile)) + } + + /// Wrapper for [`File::sync_data`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.sync_data). + pub fn sync_data(&self) -> Result<(), io::Error> { + self.file + .sync_data() + .map_err(|source| self.error(source, ErrorKind::SyncFile)) + } + + /// Wrapper for [`File::set_len`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.set_len). + pub fn set_len(&self, size: u64) -> Result<(), io::Error> { + self.file + .set_len(size) + .map_err(|source| self.error(source, ErrorKind::SetLen)) + } + + /// Wrapper for [`File::metadata`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.metadata). + pub fn metadata(&self) -> Result { + self.file + .metadata() + .map_err(|source| self.error(source, ErrorKind::Metadata)) + } + + /// Wrapper for [`File::try_clone`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.try_clone). + pub fn try_clone(&self) -> Result { + self.file + .try_clone() + .map(|file| File { + file, + path: self.path.clone(), + }) + .map_err(|source| self.error(source, ErrorKind::Clone)) + } + + /// Wrapper for [`File::set_permissions`](https://doc.rust-lang.org/stable/std/fs/struct.File.html#method.set_permissions). + pub fn set_permissions(&self, perm: fs::Permissions) -> Result<(), io::Error> { + self.file + .set_permissions(perm) + .map_err(|source| self.error(source, ErrorKind::SetPermissions)) + } + + /// Creates a [`File`](struct.File.html) from a raw file and its path. + pub fn from_parts

(file: fs::File, path: P) -> Self + where + P: Into, + { + File { + file, + path: path.into(), + } + } +} + +/// Methods added by fs-err that are not available on +/// [`std::fs::File`][std::fs::File]. +/// +/// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html +impl File { + /// Returns a reference to the underlying [`std::fs::File`][std::fs::File]. + /// + /// [std::fs::File]: https://doc.rust-lang.org/stable/std/fs/struct.File.html + pub fn file(&self) -> &fs::File { + &self.file + } + + /// Returns a reference to the path that this file was created with. + pub fn path(&self) -> &Path { + &self.path + } + + /// Wrap the error in information specific to this `File` object. + fn error(&self, source: io::Error, kind: ErrorKind) -> io::Error { + Error::new(source, kind, &self.path) + } +} + +impl Read for File { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + self.file + .read(buf) + .map_err(|source| self.error(source, ErrorKind::Read)) + } + + fn read_vectored(&mut self, bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result { + self.file + .read_vectored(bufs) + .map_err(|source| self.error(source, ErrorKind::Read)) + } +} + +impl<'a> Read for &'a File { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + (&(**self).file) + .read(buf) + .map_err(|source| self.error(source, ErrorKind::Read)) + } + + fn read_vectored(&mut self, bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result { + (&(**self).file) + .read_vectored(bufs) + .map_err(|source| self.error(source, ErrorKind::Read)) + } +} + +impl Seek for File { + fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result { + self.file + .seek(pos) + .map_err(|source| self.error(source, ErrorKind::Seek)) + } +} + +impl<'a> Seek for &'a File { + fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result { + (&(**self).file) + .seek(pos) + .map_err(|source| self.error(source, ErrorKind::Seek)) + } +} + +impl Write for File { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + self.file + .write(buf) + .map_err(|source| self.error(source, ErrorKind::Write)) + } + + fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result { + self.file + .write_vectored(bufs) + .map_err(|source| self.error(source, ErrorKind::Write)) + } + + fn flush(&mut self) -> std::io::Result<()> { + self.file + .flush() + .map_err(|source| self.error(source, ErrorKind::Flush)) + } +} + +impl<'a> Write for &'a File { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + (&(**self).file) + .write(buf) + .map_err(|source| self.error(source, ErrorKind::Write)) + } + + fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> std::io::Result { + (&(**self).file) + .write_vectored(bufs) + .map_err(|source| self.error(source, ErrorKind::Write)) + } + + fn flush(&mut self) -> std::io::Result<()> { + (&(**self).file) + .flush() + .map_err(|source| self.error(source, ErrorKind::Flush)) + } +} + +#[cfg(unix)] +mod unix { + use crate::os::unix::fs::FileExt; + use crate::ErrorKind; + use std::io; + use std::os::unix::fs::FileExt as _; + use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd}; + + impl AsRawFd for crate::File { + fn as_raw_fd(&self) -> RawFd { + self.file().as_raw_fd() + } + } + + impl IntoRawFd for crate::File { + fn into_raw_fd(self) -> RawFd { + self.file.into_raw_fd() + } + } + + impl FileExt for crate::File { + fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { + self.file() + .read_at(buf, offset) + .map_err(|err| self.error(err, ErrorKind::ReadAt)) + } + fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { + self.file() + .write_at(buf, offset) + .map_err(|err| self.error(err, ErrorKind::WriteAt)) + } + } +} + +#[cfg(windows)] +mod windows { + use crate::os::windows::fs::FileExt; + use crate::ErrorKind; + use std::io; + use std::os::windows::{ + fs::FileExt as _, + io::{AsRawHandle, IntoRawHandle, RawHandle}, + }; + + impl FileExt for crate::File { + fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result { + self.file() + .seek_read(buf, offset) + .map_err(|err| self.error(err, ErrorKind::SeekRead)) + } + + fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result { + self.file() + .seek_write(buf, offset) + .map_err(|err| self.error(err, ErrorKind::SeekWrite)) + } + } + + impl AsRawHandle for crate::File { + fn as_raw_handle(&self) -> RawHandle { + self.file().as_raw_handle() + } + } + + // can't be implemented, because the trait doesn't give us a Path + // impl std::os::windows::io::FromRawHandle for crate::File { + // } + + impl IntoRawHandle for crate::File { + fn into_raw_handle(self) -> RawHandle { + self.file.into_raw_handle() + } + } +} diff --git a/vendor/fs-err/src/lib.rs b/vendor/fs-err/src/lib.rs new file mode 100644 index 000000000..3cc8a3b4d --- /dev/null +++ b/vendor/fs-err/src/lib.rs @@ -0,0 +1,246 @@ +/*! +fs-err is a drop-in replacement for [`std::fs`][std::fs] that provides more +helpful messages on errors. Extra information includes which operations was +attmpted and any involved paths. + +# Error Messages + +Using [`std::fs`][std::fs], if this code fails: + +```no_run +# use std::fs::File; +let file = File::open("does not exist.txt")?; +# Ok::<(), std::io::Error>(()) +``` + +The error message that Rust gives you isn't very useful: + +```txt +The system cannot find the file specified. (os error 2) +``` + +...but if we use fs-err instead, our error contains more actionable information: + +```txt +failed to open file `does not exist.txt` + caused by: The system cannot find the file specified. (os error 2) +``` + +# Usage + +fs-err's API is the same as [`std::fs`][std::fs], so migrating code to use it is easy. + +```no_run +// use std::fs; +use fs_err as fs; + +let contents = fs::read_to_string("foo.txt")?; + +println!("Read foo.txt: {}", contents); + +# Ok::<(), std::io::Error>(()) +``` + +fs-err uses [`std::io::Error`][std::io::Error] for all errors. This helps fs-err +compose well with traits from the standard library like +[`std::io::Read`][std::io::Read] and crates that use them like +[`serde_json`][serde_json]: + +```no_run +use fs_err::File; + +let file = File::open("my-config.json")?; + +// If an I/O error occurs inside serde_json, the error will include a file path +// as well as what operation was being performed. +let decoded: Vec = serde_json::from_reader(file)?; + +println!("Program config: {:?}", decoded); + +# Ok::<(), Box>(()) +``` + +[std::fs]: https://doc.rust-lang.org/stable/std/fs/ +[std::io::Error]: https://doc.rust-lang.org/stable/std/io/struct.Error.html +[std::io::Read]: https://doc.rust-lang.org/stable/std/io/trait.Read.html +[serde_json]: https://crates.io/crates/serde_json +*/ + +#![doc(html_root_url = "https://docs.rs/fs-err/2.5.0")] +#![deny(missing_debug_implementations, missing_docs)] + +mod dir; +mod errors; +mod file; +mod open_options; +pub mod os; +mod path; + +use std::fs; +use std::io::{self, Read, Write}; +use std::path::{Path, PathBuf}; + +use errors::{Error, ErrorKind, SourceDestError, SourceDestErrorKind}; + +pub use dir::*; +pub use file::*; +pub use open_options::OpenOptions; +pub use path::PathExt; + +/// Wrapper for [`fs::read`](https://doc.rust-lang.org/stable/std/fs/fn.read.html). +pub fn read>(path: P) -> io::Result> { + let path = path.as_ref(); + let mut file = file::open(path.as_ref()).map_err(|err_gen| err_gen(path.to_path_buf()))?; + let mut bytes = Vec::with_capacity(initial_buffer_size(&file)); + file.read_to_end(&mut bytes) + .map_err(|err| Error::new(err, ErrorKind::Read, path))?; + Ok(bytes) +} + +/// Wrapper for [`fs::read_to_string`](https://doc.rust-lang.org/stable/std/fs/fn.read_to_string.html). +pub fn read_to_string>(path: P) -> io::Result { + let path = path.as_ref(); + let mut file = file::open(path.as_ref()).map_err(|err_gen| err_gen(path.to_path_buf()))?; + let mut string = String::with_capacity(initial_buffer_size(&file)); + file.read_to_string(&mut string) + .map_err(|err| Error::new(err, ErrorKind::Read, path))?; + Ok(string) +} + +/// Wrapper for [`fs::write`](https://doc.rust-lang.org/stable/std/fs/fn.write.html). +pub fn write, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> { + let path = path.as_ref(); + file::create(path) + .map_err(|err_gen| err_gen(path.to_path_buf()))? + .write_all(contents.as_ref()) + .map_err(|err| Error::new(err, ErrorKind::Write, path)) +} + +/// Wrapper for [`fs::copy`](https://doc.rust-lang.org/stable/std/fs/fn.copy.html). +pub fn copy(from: P, to: Q) -> io::Result +where + P: AsRef, + Q: AsRef, +{ + let from = from.as_ref(); + let to = to.as_ref(); + fs::copy(from, to) + .map_err(|source| SourceDestError::new(source, SourceDestErrorKind::Copy, from, to)) +} + +/// Wrapper for [`fs::create_dir`](https://doc.rust-lang.org/stable/std/fs/fn.create_dir.html). +pub fn create_dir

(path: P) -> io::Result<()> +where + P: AsRef, +{ + let path = path.as_ref(); + fs::create_dir(path).map_err(|source| Error::new(source, ErrorKind::CreateDir, path)) +} + +/// Wrapper for [`fs::create_dir_all`](https://doc.rust-lang.org/stable/std/fs/fn.create_dir_all.html). +pub fn create_dir_all

(path: P) -> io::Result<()> +where + P: AsRef, +{ + let path = path.as_ref(); + fs::create_dir_all(path).map_err(|source| Error::new(source, ErrorKind::CreateDir, path)) +} + +/// Wrapper for [`fs::remove_dir`](https://doc.rust-lang.org/stable/std/fs/fn.remove_dir.html). +pub fn remove_dir

(path: P) -> io::Result<()> +where + P: AsRef, +{ + let path = path.as_ref(); + fs::remove_dir(path).map_err(|source| Error::new(source, ErrorKind::RemoveDir, path)) +} + +/// Wrapper for [`fs::remove_dir_all`](https://doc.rust-lang.org/stable/std/fs/fn.remove_dir_all.html). +pub fn remove_dir_all

(path: P) -> io::Result<()> +where + P: AsRef, +{ + let path = path.as_ref(); + fs::remove_dir_all(path).map_err(|source| Error::new(source, ErrorKind::RemoveDir, path)) +} + +/// Wrapper for [`fs::remove_file`](https://doc.rust-lang.org/stable/std/fs/fn.remove_file.html). +pub fn remove_file

(path: P) -> io::Result<()> +where + P: AsRef, +{ + let path = path.as_ref(); + fs::remove_file(path).map_err(|source| Error::new(source, ErrorKind::RemoveFile, path)) +} + +/// Wrapper for [`fs::metadata`](https://doc.rust-lang.org/stable/std/fs/fn.metadata.html). +pub fn metadata>(path: P) -> io::Result { + let path = path.as_ref(); + fs::metadata(path).map_err(|source| Error::new(source, ErrorKind::Metadata, path)) +} + +/// Wrapper for [`fs::canonicalize`](https://doc.rust-lang.org/stable/std/fs/fn.canonicalize.html). +pub fn canonicalize>(path: P) -> io::Result { + let path = path.as_ref(); + fs::canonicalize(path).map_err(|source| Error::new(source, ErrorKind::Canonicalize, path)) +} + +/// Wrapper for [`fs::hard_link`](https://doc.rust-lang.org/stable/std/fs/fn.hard_link.html). +pub fn hard_link, Q: AsRef>(src: P, dst: Q) -> io::Result<()> { + let src = src.as_ref(); + let dst = dst.as_ref(); + fs::hard_link(src, dst) + .map_err(|source| SourceDestError::new(source, SourceDestErrorKind::HardLink, src, dst)) +} + +/// Wrapper for [`fs::read_link`](https://doc.rust-lang.org/stable/std/fs/fn.read_link.html). +pub fn read_link>(path: P) -> io::Result { + let path = path.as_ref(); + fs::read_link(path).map_err(|source| Error::new(source, ErrorKind::ReadLink, path)) +} + +/// Wrapper for [`fs::rename`](https://doc.rust-lang.org/stable/std/fs/fn.rename.html). +pub fn rename, Q: AsRef>(from: P, to: Q) -> io::Result<()> { + let from = from.as_ref(); + let to = to.as_ref(); + fs::rename(from, to) + .map_err(|source| SourceDestError::new(source, SourceDestErrorKind::Rename, from, to)) +} + +/// Wrapper for [`fs::soft_link`](https://doc.rust-lang.org/stable/std/fs/fn.soft_link.html). +#[deprecated = "replaced with std::os::unix::fs::symlink and \ +std::os::windows::fs::{symlink_file, symlink_dir}"] +pub fn soft_link, Q: AsRef>(src: P, dst: Q) -> io::Result<()> { + let src = src.as_ref(); + let dst = dst.as_ref(); + #[allow(deprecated)] + fs::soft_link(src, dst) + .map_err(|source| SourceDestError::new(source, SourceDestErrorKind::SoftLink, src, dst)) +} + +/// Wrapper for [`fs::symlink_metadata`](https://doc.rust-lang.org/stable/std/fs/fn.symlink_metadata.html). +pub fn symlink_metadata>(path: P) -> io::Result { + let path = path.as_ref(); + fs::symlink_metadata(path) + .map_err(|source| Error::new(source, ErrorKind::SymlinkMetadata, path)) +} + +/// Wrapper for [`fs::set_permissions`](https://doc.rust-lang.org/stable/std/fs/fn.set_permissions.html). +pub fn set_permissions>(path: P, perm: fs::Permissions) -> io::Result<()> { + let path = path.as_ref(); + fs::set_permissions(path, perm) + .map_err(|source| Error::new(source, ErrorKind::SetPermissions, path)) +} + +fn initial_buffer_size(file: &std::fs::File) -> usize { + file.metadata().map(|m| m.len() as usize + 1).unwrap_or(0) +} + +pub(crate) use private::Sealed; +mod private { + pub trait Sealed {} + + impl Sealed for crate::File {} + impl Sealed for std::path::Path {} + impl Sealed for crate::OpenOptions {} +} diff --git a/vendor/fs-err/src/open_options.rs b/vendor/fs-err/src/open_options.rs new file mode 100644 index 000000000..2a11a3974 --- /dev/null +++ b/vendor/fs-err/src/open_options.rs @@ -0,0 +1,133 @@ +use std::{fs, io, path::PathBuf}; +#[derive(Clone, Debug)] +/// Wrapper around [`std::fs::OptionOptions`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html) +pub struct OpenOptions(fs::OpenOptions); + +impl OpenOptions { + /// Wrapper for [`std::fs::OpenOptions::new`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.new) + pub fn new() -> Self { + OpenOptions(fs::OpenOptions::new()) + } + + /// Wrapper for [`std::fs::OpenOptions::read`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.read) + pub fn read(&mut self, read: bool) -> &mut Self { + self.0.read(read); + self + } + + /// Wrapper for [`std::fs::OpenOptions::write`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.write) + pub fn write(&mut self, write: bool) -> &mut Self { + self.0.write(write); + self + } + + /// Wrapper for [`std::fs::OpenOptions::append`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.append) + pub fn append(&mut self, append: bool) -> &mut Self { + self.0.append(append); + self + } + + /// Wrapper for [`std::fs::OpenOptions::truncate`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.truncate) + pub fn truncate(&mut self, truncate: bool) -> &mut Self { + self.0.truncate(truncate); + self + } + + /// Wrapper for [`std::fs::OpenOptions::create`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.create) + pub fn create(&mut self, create: bool) -> &mut Self { + self.0.create(create); + self + } + + /// Wrapper for [`std::fs::OpenOptions::create_new`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.create_new) + pub fn create_new(&mut self, create_new: bool) -> &mut Self { + self.0.create_new(create_new); + self + } + + /// Wrapper for [`std::fs::OpenOptions::open`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.open) + pub fn open

(&self, path: P) -> io::Result + where + P: Into, + { + // We have to either duplicate the logic or call the deprecated method here. + // We can't let the deprecated function call this method, because we can't construct + // `&fs_err::OpenOptions` from `&fs::OpenOptions` without cloning + // (although cloning would probably be cheap). + #[allow(deprecated)] + crate::File::from_options(path.into(), self.options()) + } +} + +/// Methods added by fs-err that are not available on +/// [`std::fs::OpenOptions`](https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html). +impl OpenOptions { + /// Constructs `Self` from [`std::fs::OpenOptions`](https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html) + pub fn from_options(options: fs::OpenOptions) -> Self { + Self(options) + } + + /// Returns a reference to the underlying [`std::fs::OpenOptions`](https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html). + /// + /// Note that calling `open()` on this reference will NOT give you the improved errors from fs-err. + pub fn options(&self) -> &fs::OpenOptions { + &self.0 + } + + /// Returns a mutable reference to the underlying [`std::fs::OpenOptions`](https://doc.rust-lang.org/stable/std/fs/struct.OpenOptions.html). + /// + /// This allows you to change settings that don't yet have wrappers in fs-err. + /// Note that calling `open()` on this reference will NOT give you the improved errors from fs-err. + pub fn options_mut(&mut self) -> &mut fs::OpenOptions { + &mut self.0 + } +} + +#[cfg(unix)] +mod unix { + use crate::os::unix::fs::OpenOptionsExt; + use std::os::unix::fs::OpenOptionsExt as _; + impl OpenOptionsExt for crate::OpenOptions { + fn mode(&mut self, mode: u32) -> &mut Self { + self.options_mut().mode(mode); + self + } + + fn custom_flags(&mut self, flags: i32) -> &mut Self { + self.options_mut().custom_flags(flags); + self + } + } +} + +#[cfg(windows)] +mod windows { + use crate::os::windows::fs::OpenOptionsExt; + use std::os::windows::fs::OpenOptionsExt as _; + + impl OpenOptionsExt for crate::OpenOptions { + fn access_mode(&mut self, access: u32) -> &mut Self { + self.options_mut().access_mode(access); + self + } + + fn share_mode(&mut self, val: u32) -> &mut Self { + self.options_mut().share_mode(val); + self + } + fn custom_flags(&mut self, flags: u32) -> &mut Self { + self.options_mut().custom_flags(flags); + self + } + + fn attributes(&mut self, val: u32) -> &mut Self { + self.options_mut().attributes(val); + self + } + + fn security_qos_flags(&mut self, flags: u32) -> &mut Self { + self.options_mut().security_qos_flags(flags); + self + } + } +} diff --git a/vendor/fs-err/src/os.rs b/vendor/fs-err/src/os.rs new file mode 100644 index 000000000..b801e6076 --- /dev/null +++ b/vendor/fs-err/src/os.rs @@ -0,0 +1,11 @@ +//! OS-specific functionality. + +// The std-library has a couple more platforms than just `unix` for which these apis +// are defined, but we're using just `unix` here. We can always expand later. +#[cfg(unix)] +/// Platform-specific extensions for Unix platforms. +pub mod unix; + +#[cfg(windows)] +/// Platform-specific extensions for Windows. +pub mod windows; diff --git a/vendor/fs-err/src/os/unix.rs b/vendor/fs-err/src/os/unix.rs new file mode 100644 index 000000000..1c0bbc24d --- /dev/null +++ b/vendor/fs-err/src/os/unix.rs @@ -0,0 +1,38 @@ +/// Unix-specific extensions to wrappers in `fs_err` for `std::fs` types. +pub mod fs { + use std::io; + use std::path::Path; + + use crate::SourceDestError; + use crate::SourceDestErrorKind; + + /// Wrapper for [`std::os::unix::fs::symlink`](https://doc.rust-lang.org/std/os/unix/fs/fn.symlink.html) + pub fn symlink, Q: AsRef>(src: P, dst: Q) -> io::Result<()> { + let src = src.as_ref(); + let dst = dst.as_ref(); + std::os::unix::fs::symlink(src, dst) + .map_err(|err| SourceDestError::new(err, SourceDestErrorKind::Symlink, src, dst)) + } + + /// Wrapper for [`std::os::unix::fs::FileExt`](https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html). + /// + /// The std traits might be extended in the future (See issue [#49961](https://github.com/rust-lang/rust/issues/49961#issuecomment-382751777)). + /// This trait is sealed and can not be implemented by other crates. + pub trait FileExt: crate::Sealed { + /// Wrapper for [`FileExt::read_at`](https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#tymethod.read_at) + fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result; + /// Wrapper for [`FileExt::write_at`](https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#tymethod.write_at) + fn write_at(&self, buf: &[u8], offset: u64) -> io::Result; + } + + /// Wrapper for [`std::os::unix::fs::OpenOptionsExt`](https://doc.rust-lang.org/std/os/unix/fs/trait.OpenOptionsExt.html) + /// + /// The std traits might be extended in the future (See issue [#49961](https://github.com/rust-lang/rust/issues/49961#issuecomment-382751777)). + /// This trait is sealed and can not be implemented by other crates. + pub trait OpenOptionsExt: crate::Sealed { + /// Wapper for [`OpenOptionsExt::mode`](https://doc.rust-lang.org/std/os/unix/fs/trait.OpenOptionsExt.html#tymethod.mode) + fn mode(&mut self, mode: u32) -> &mut Self; + /// Wapper for [`OpenOptionsExt::custom_flags`](https://doc.rust-lang.org/std/os/unix/fs/trait.OpenOptionsExt.html#tymethod.custom_flags) + fn custom_flags(&mut self, flags: i32) -> &mut Self; + } +} diff --git a/vendor/fs-err/src/os/windows.rs b/vendor/fs-err/src/os/windows.rs new file mode 100644 index 000000000..3aaa4a2b8 --- /dev/null +++ b/vendor/fs-err/src/os/windows.rs @@ -0,0 +1,49 @@ +/// Windows-specific extensions to wrappers in `fs_err` for `std::fs` types. +pub mod fs { + use crate::{SourceDestError, SourceDestErrorKind}; + use std::io; + use std::path::Path; + /// Wrapper for [std::os::windows::fs::symlink_dir](https://doc.rust-lang.org/std/os/windows/fs/fn.symlink_dir.html) + pub fn symlink_dir, Q: AsRef>(src: P, dst: Q) -> io::Result<()> { + let src = src.as_ref(); + let dst = dst.as_ref(); + std::os::windows::fs::symlink_dir(src, dst) + .map_err(|err| SourceDestError::new(err, SourceDestErrorKind::SymlinkDir, src, dst)) + } + + /// Wrapper for [std::os::windows::fs::symlink_file](https://doc.rust-lang.org/std/os/windows/fs/fn.symlink_file.html) + pub fn symlink_file, Q: AsRef>(src: P, dst: Q) -> io::Result<()> { + let src = src.as_ref(); + let dst = dst.as_ref(); + std::os::windows::fs::symlink_file(src, dst) + .map_err(|err| SourceDestError::new(err, SourceDestErrorKind::SymlinkFile, src, dst)) + } + + /// Wrapper for [`std::os::windows::fs::FileExt`](https://doc.rust-lang.org/std/os/windows/fs/trait.FileExt.html). + /// + /// The std traits might be extended in the future (See issue [#49961](https://github.com/rust-lang/rust/issues/49961#issuecomment-382751777)). + /// This trait is sealed and can not be implemented by other crates. + pub trait FileExt: crate::Sealed { + /// Wrapper for [`FileExt::seek_read`](https://doc.rust-lang.org/std/os/windows/fs/trait.FileExt.html#tymethod.seek_read) + fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result; + /// Wrapper for [`FileExt::seek_wriite`](https://doc.rust-lang.org/std/os/windows/fs/trait.FileExt.html#tymethod.seek_write) + fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result; + } + + /// Wrapper for [`std::os::windows::fs::OpenOptionsExt`](https://doc.rust-lang.org/std/os/windows/fs/trait.OpenOptionsExt.html) + /// + /// The std traits might be extended in the future (See issue [#49961](https://github.com/rust-lang/rust/issues/49961#issuecomment-382751777)). + /// This trait is sealed and can not be implemented by other crates. + pub trait OpenOptionsExt: crate::Sealed { + /// Wrapper for [`OpenOptionsExt::access_mode`](https://doc.rust-lang.org/std/os/windows/fs/trait.OpenOptionsExt.html#tymethod.access_mode) + fn access_mode(&mut self, access: u32) -> &mut Self; + /// Wrapper for [`OpenOptionsExt::share_mode`](https://doc.rust-lang.org/std/os/windows/fs/trait.OpenOptionsExt.html#tymethod.share_mode) + fn share_mode(&mut self, val: u32) -> &mut Self; + /// Wrapper for [`OpenOptionsExt::custom_flags`](https://doc.rust-lang.org/std/os/windows/fs/trait.OpenOptionsExt.html#tymethod.custom_flags) + fn custom_flags(&mut self, flags: u32) -> &mut Self; + /// Wrapper for [`OpenOptionsExt::attributes`](https://doc.rust-lang.org/std/os/windows/fs/trait.OpenOptionsExt.html#tymethod.attributes) + fn attributes(&mut self, val: u32) -> &mut Self; + /// Wrapper for [`OpenOptionsExt::security_qos_flags`](https://doc.rust-lang.org/std/os/windows/fs/trait.OpenOptionsExt.html#tymethod.security_qos_flags) + fn security_qos_flags(&mut self, flags: u32) -> &mut Self; + } +} diff --git a/vendor/fs-err/src/path.rs b/vendor/fs-err/src/path.rs new file mode 100644 index 000000000..ed6b9eaf1 --- /dev/null +++ b/vendor/fs-err/src/path.rs @@ -0,0 +1,43 @@ +use std::fs; +use std::io; +use std::path::{Path, PathBuf}; + +/// Defines aliases on [`Path`](https://doc.rust-lang.org/std/path/struct.Path.html) for `fs_err` functions. +/// +/// This trait is sealed and can not be implemented by other crates. +// +// Because noone else can implement it, we can add methods backwards-compatibly. +pub trait PathExt: crate::Sealed { + /// Wrapper for [`crate::metadata`]. + fn fs_err_metadata(&self) -> io::Result; + /// Wrapper for [`crate::symlink_metadata`]. + fn fs_err_symlink_metadata(&self) -> io::Result; + /// Wrapper for [`crate::canonicalize`]. + fn fs_err_canonicalize(&self) -> io::Result; + /// Wrapper for [`crate::read_link`]. + fn fs_err_read_link(&self) -> io::Result; + /// Wrapper for [`crate::read_dir`]. + fn fs_err_read_dir(&self) -> io::Result; +} + +impl PathExt for Path { + fn fs_err_metadata(&self) -> io::Result { + crate::metadata(self) + } + + fn fs_err_symlink_metadata(&self) -> io::Result { + crate::symlink_metadata(self) + } + + fn fs_err_canonicalize(&self) -> io::Result { + crate::canonicalize(self) + } + + fn fs_err_read_link(&self) -> io::Result { + crate::read_link(self) + } + + fn fs_err_read_dir(&self) -> io::Result { + crate::read_dir(self) + } +} -- cgit v1.2.3