зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1806766 - Update fs-err to 2.9.0. r=emilio,supply-chain-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D165361
This commit is contained in:
Родитель
46e140661f
Коммит
9d3c2288a3
|
@ -1872,9 +1872,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "fs-err"
|
||||
version = "2.8.1"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64db3e262960f0662f43a6366788d5f10f7f244b8f7d7d987f560baf5ded5c50"
|
||||
checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
|
|
|
@ -607,6 +607,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
|
|||
criteria = "safe-to-deploy"
|
||||
delta = "2.7.0 -> 2.8.1"
|
||||
|
||||
[[audits.fs-err]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "2.8.1 -> 2.9.0"
|
||||
|
||||
[[audits.futures]]
|
||||
who = "Mike Hommey <mh+mozilla@glandium.org>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"CHANGELOG.md":"fb2609e5837d71e923def1765b6addc4d11b0b5040e7eb9bdbf50d59a4a5cd42","Cargo.toml":"b468e8d560ea6e30277c2ee438ac650bbb2397f5b62da911126c180921aa5d29","LICENSE-APACHE":"7cfd738c53d61c79f07e348f622bf7707c9084237054d37fbe07788a75f5881c","LICENSE-MIT":"36516aefdc84c5d5a1e7485425913a22dbda69eb1930c5e84d6ae4972b5194b9","README.md":"adbf428f33a04028cc8db98d7b75bdcf28d0edb5e792867578bcb93f1784abec","src/dir.rs":"c5255382d7357f2fbcb0b45325a343277d347f0dd0b5f0e5ff74cb808020795d","src/errors.rs":"f04771790f55627fdc39de43a1d16f7d0125bbf48d4a1c8a70921f2670dd3eaa","src/file.rs":"4516834bc52f1219f10e369bf570fd432493ceaf5d52d239d93a5e69ceaed0aa","src/lib.rs":"1a10c04bde2bc3ae30cc328afb0aa00ac98ab80c6bfff5ae94ee7e5bdbe86ec8","src/open_options.rs":"304c5be36b5a6c5ecc2c731e2956627494945d093952c879d8f3c5b15216b1d0","src/os.rs":"54fe6cb71a24592de1cb4e1fcebdeaba5e58b26925dbf2dc868e8dd0b0a7bef7","src/os/unix.rs":"21ab862305b9e1034c41bb4be31b1f3d43e3d208ca3e622211b6b54d1bbd9acc","src/os/windows.rs":"4cf0530becb6fed439f469e1f22f57de9ae2ac15e39f2a973f4734aee6267ed0","src/path.rs":"a026ae234184ed1bbadd9051099e201c3ac6309b1fd939d1b2d2b2a7cb82230d"},"package":"64db3e262960f0662f43a6366788d5f10f7f244b8f7d7d987f560baf5ded5c50"}
|
||||
{"files":{"CHANGELOG.md":"b17b12bee003d65ea5f1593ffd57faf8d8f98b036137cca857b5c203d1c2ae0b","Cargo.toml":"4ee30dec20735529b07d148071ecbe148d34a9fe1f83ed9f6d820230f41034bb","LICENSE-APACHE":"7cfd738c53d61c79f07e348f622bf7707c9084237054d37fbe07788a75f5881c","LICENSE-MIT":"36516aefdc84c5d5a1e7485425913a22dbda69eb1930c5e84d6ae4972b5194b9","README.md":"adbf428f33a04028cc8db98d7b75bdcf28d0edb5e792867578bcb93f1784abec","src/dir.rs":"c5255382d7357f2fbcb0b45325a343277d347f0dd0b5f0e5ff74cb808020795d","src/errors.rs":"f04771790f55627fdc39de43a1d16f7d0125bbf48d4a1c8a70921f2670dd3eaa","src/file.rs":"4516834bc52f1219f10e369bf570fd432493ceaf5d52d239d93a5e69ceaed0aa","src/lib.rs":"9cdc8a3cac73976d7c121a1b9eb63a3a2bebdd6533a67b22bc3628952578fde2","src/open_options.rs":"304c5be36b5a6c5ecc2c731e2956627494945d093952c879d8f3c5b15216b1d0","src/os.rs":"54fe6cb71a24592de1cb4e1fcebdeaba5e58b26925dbf2dc868e8dd0b0a7bef7","src/os/unix.rs":"21ab862305b9e1034c41bb4be31b1f3d43e3d208ca3e622211b6b54d1bbd9acc","src/os/windows.rs":"4cf0530becb6fed439f469e1f22f57de9ae2ac15e39f2a973f4734aee6267ed0","src/path.rs":"a026ae234184ed1bbadd9051099e201c3ac6309b1fd939d1b2d2b2a7cb82230d","src/tokio/dir_builder.rs":"b004b6b5aeda08201dbc0ecda841f60cf06361e709cfef891356980543509b87","src/tokio/file.rs":"fb59dd43133f22b85314d28a098dc68281f4dc29a109d79fcbf2e76224830ad8","src/tokio/mod.rs":"cedd71363c524436ddae1e3dacc5ce16959b480c4f1c470ca44b2a5b59a9b1a2","src/tokio/open_options.rs":"c6ccc8f9c89ea7f8a1b96ad927a8dfcb169e77d9f40b01f0cfdccd4e1869a9c6","src/tokio/read_dir.rs":"8f3a2aaa029354420563ff621f72defb228f196a32bc113d89c99944fac56086"},"package":"0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541"}
|
|
@ -1,5 +1,9 @@
|
|||
# fs-err Changelog
|
||||
|
||||
## 2.9.0
|
||||
|
||||
* Add wrappers for [`tokio::fs`](https://docs.rs/tokio/latest/tokio/fs/index.html) ([#40](https://github.com/andrewhickman/fs-err/pull/40)).
|
||||
|
||||
## 2.8.1
|
||||
|
||||
* Fixed docs.rs build
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
[package]
|
||||
edition = "2018"
|
||||
name = "fs-err"
|
||||
version = "2.8.1"
|
||||
version = "2.9.0"
|
||||
authors = ["Andrew Hickman <andrew.hickman1@sky.com>"]
|
||||
exclude = [
|
||||
".github",
|
||||
|
@ -46,7 +46,11 @@ rustdoc-args = [
|
|||
"docsrs",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
[dependencies.tokio]
|
||||
version = "1.21"
|
||||
features = ["fs"]
|
||||
optional = true
|
||||
default_features = false
|
||||
|
||||
[dev-dependencies.serde_json]
|
||||
version = "1.0.64"
|
||||
|
|
|
@ -66,7 +66,7 @@ println!("Program config: {:?}", decoded);
|
|||
[serde_json]: https://crates.io/crates/serde_json
|
||||
*/
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/fs-err/2.8.1")]
|
||||
#![doc(html_root_url = "https://docs.rs/fs-err/2.9.0")]
|
||||
#![deny(missing_debug_implementations, missing_docs)]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
|
||||
|
@ -76,6 +76,9 @@ mod file;
|
|||
mod open_options;
|
||||
pub mod os;
|
||||
mod path;
|
||||
#[cfg(feature = "tokio")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub mod tokio;
|
||||
|
||||
use std::fs;
|
||||
use std::io::{self, Read, Write};
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
use crate::errors::{Error, ErrorKind};
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
|
||||
/// A builder for creating directories in various manners.
|
||||
///
|
||||
/// This is a wrapper around [`tokio::fs::DirBuilder`].
|
||||
#[derive(Debug, Default)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub struct DirBuilder {
|
||||
inner: tokio::fs::DirBuilder,
|
||||
}
|
||||
|
||||
impl DirBuilder {
|
||||
/// Creates a new set of options with default mode/security settings for all
|
||||
/// platforms and also non-recursive.
|
||||
///
|
||||
/// This is a wrapper version of [`tokio::fs::DirBuilder::new`]
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use fs_err::tokio::DirBuilder;
|
||||
///
|
||||
/// let builder = DirBuilder::new();
|
||||
/// ```
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
/// Wrapper around [`tokio::fs::DirBuilder::recursive`].
|
||||
pub fn recursive(&mut self, recursive: bool) -> &mut Self {
|
||||
self.inner.recursive(recursive);
|
||||
self
|
||||
}
|
||||
|
||||
/// Wrapper around [`tokio::fs::DirBuilder::create`].
|
||||
pub async fn create(&self, path: impl AsRef<Path>) -> io::Result<()> {
|
||||
let path = path.as_ref();
|
||||
self.inner
|
||||
.create(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::CreateDir, path))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl DirBuilder {
|
||||
/// Wrapper around [`tokio::fs::DirBuilder::mode`].
|
||||
pub fn mode(&mut self, mode: u32) -> &mut Self {
|
||||
self.inner.mode(mode);
|
||||
self
|
||||
}
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
use crate::errors::{Error, ErrorKind};
|
||||
use std::fs::{Metadata, Permissions};
|
||||
use std::io;
|
||||
use std::io::{IoSlice, SeekFrom};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::pin::Pin;
|
||||
use std::task::{ready, Context, Poll};
|
||||
use tokio::fs;
|
||||
use tokio::fs::File as TokioFile;
|
||||
use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite, ReadBuf};
|
||||
|
||||
/// Wrapper around [`tokio::fs::File`] which adds more helpful
|
||||
/// information to all errors.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub struct File {
|
||||
tokio: fs::File,
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
impl File {
|
||||
/// Wrapper for [`tokio::fs::File::open`].
|
||||
pub async fn open(path: impl Into<PathBuf>) -> io::Result<File> {
|
||||
let path = path.into();
|
||||
let f = TokioFile::open(&path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::OpenFile, &path))?;
|
||||
Ok(File::from_parts(f, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::File::create`].
|
||||
pub async fn create(path: impl Into<PathBuf>) -> io::Result<File> {
|
||||
let path = path.into();
|
||||
match TokioFile::create(&path).await {
|
||||
Ok(f) => Ok(File::from_parts(f, path)),
|
||||
Err(err) => Err(Error::build(err, ErrorKind::CreateFile, &path)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::File::from_std`].
|
||||
pub fn from_std(std: crate::File) -> File {
|
||||
let (std, path) = std.into_parts();
|
||||
File::from_parts(TokioFile::from_std(std), path)
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::File::sync_all`].
|
||||
pub async fn sync_all(&self) -> io::Result<()> {
|
||||
self.tokio
|
||||
.sync_all()
|
||||
.await
|
||||
.map_err(|err| self.error(err, ErrorKind::SyncFile))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::File::sync_data`].
|
||||
pub async fn sync_data(&self) -> io::Result<()> {
|
||||
self.tokio
|
||||
.sync_data()
|
||||
.await
|
||||
.map_err(|err| self.error(err, ErrorKind::SyncFile))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::File::set_len`].
|
||||
pub async fn set_len(&self, size: u64) -> io::Result<()> {
|
||||
self.tokio
|
||||
.set_len(size)
|
||||
.await
|
||||
.map_err(|err| self.error(err, ErrorKind::SetLen))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::File::metadata`].
|
||||
pub async fn metadata(&self) -> io::Result<Metadata> {
|
||||
self.tokio
|
||||
.metadata()
|
||||
.await
|
||||
.map_err(|err| self.error(err, ErrorKind::Metadata))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::File::try_clone`].
|
||||
pub async fn try_clone(&self) -> io::Result<File> {
|
||||
match self.tokio.try_clone().await {
|
||||
Ok(file) => Ok(File::from_parts(file, self.path.clone())),
|
||||
Err(err) => Err(self.error(err, ErrorKind::Clone)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::File::into_std`].
|
||||
pub async fn into_std(self) -> crate::File {
|
||||
crate::File::from_parts(self.tokio.into_std().await, self.path)
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::File::try_into_std`].
|
||||
pub fn try_into_std(self) -> Result<crate::File, File> {
|
||||
match self.tokio.try_into_std() {
|
||||
Ok(f) => Ok(crate::File::from_parts(f, self.path)),
|
||||
Err(f) => Err(File::from_parts(f, self.path)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::File::set_permissions`].
|
||||
pub async fn set_permissions(&self, perm: Permissions) -> io::Result<()> {
|
||||
self.tokio
|
||||
.set_permissions(perm)
|
||||
.await
|
||||
.map_err(|err| self.error(err, ErrorKind::SetPermissions))
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods added by fs-err that are not available on
|
||||
/// [`tokio::fs::File`].
|
||||
impl File {
|
||||
/// Creates a [`File`](struct.File.html) from a raw file and its path.
|
||||
pub fn from_parts<P>(file: TokioFile, path: P) -> Self
|
||||
where
|
||||
P: Into<PathBuf>,
|
||||
{
|
||||
File {
|
||||
tokio: file,
|
||||
path: path.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract the raw file and its path from this [`File`](struct.File.html).
|
||||
pub fn into_parts(self) -> (TokioFile, PathBuf) {
|
||||
(self.tokio, self.path)
|
||||
}
|
||||
|
||||
/// Returns a reference to the underlying [`tokio::fs::File`].
|
||||
pub fn file(&self) -> &TokioFile {
|
||||
&self.tokio
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the underlying [`tokio::fs::File`].
|
||||
pub fn file_mut(&mut self) -> &mut TokioFile {
|
||||
&mut self.tokio
|
||||
}
|
||||
|
||||
/// 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::build(source, kind, &self.path)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<crate::File> for File {
|
||||
fn from(f: crate::File) -> Self {
|
||||
let (f, path) = f.into_parts();
|
||||
File::from_parts(f.into(), path)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<File> for TokioFile {
|
||||
fn from(f: File) -> Self {
|
||||
f.into_parts().0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl std::os::unix::io::AsRawFd for File {
|
||||
fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
|
||||
self.tokio.as_raw_fd()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl std::os::windows::io::AsRawHandle for File {
|
||||
fn as_raw_handle(&self) -> std::os::windows::io::RawHandle {
|
||||
self.tokio.as_raw_handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncRead for File {
|
||||
fn poll_read(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &mut ReadBuf<'_>,
|
||||
) -> Poll<io::Result<()>> {
|
||||
Poll::Ready(
|
||||
ready!(Pin::new(&mut self.tokio).poll_read(cx, buf))
|
||||
.map_err(|err| self.error(err, ErrorKind::Read)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncSeek for File {
|
||||
fn start_seek(mut self: Pin<&mut Self>, position: SeekFrom) -> io::Result<()> {
|
||||
Pin::new(&mut self.tokio)
|
||||
.start_seek(position)
|
||||
.map_err(|err| self.error(err, ErrorKind::Seek))
|
||||
}
|
||||
|
||||
fn poll_complete(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<u64>> {
|
||||
Poll::Ready(
|
||||
ready!(Pin::new(&mut self.tokio).poll_complete(cx))
|
||||
.map_err(|err| self.error(err, ErrorKind::Seek)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsyncWrite for File {
|
||||
fn poll_write(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
buf: &[u8],
|
||||
) -> Poll<io::Result<usize>> {
|
||||
Poll::Ready(
|
||||
ready!(Pin::new(&mut self.tokio).poll_write(cx, buf))
|
||||
.map_err(|err| self.error(err, ErrorKind::Write)),
|
||||
)
|
||||
}
|
||||
|
||||
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
Poll::Ready(
|
||||
ready!(Pin::new(&mut self.tokio).poll_flush(cx))
|
||||
.map_err(|err| self.error(err, ErrorKind::Flush)),
|
||||
)
|
||||
}
|
||||
|
||||
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
|
||||
Poll::Ready(
|
||||
ready!(Pin::new(&mut self.tokio).poll_shutdown(cx))
|
||||
.map_err(|err| self.error(err, ErrorKind::Flush)),
|
||||
)
|
||||
}
|
||||
|
||||
fn poll_write_vectored(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
bufs: &[IoSlice<'_>],
|
||||
) -> Poll<io::Result<usize>> {
|
||||
Poll::Ready(
|
||||
ready!(Pin::new(&mut self.tokio).poll_write_vectored(cx, bufs))
|
||||
.map_err(|err| self.error(err, ErrorKind::Write)),
|
||||
)
|
||||
}
|
||||
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
self.tokio.is_write_vectored()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
//! Tokio-specific wrappers that use `fs_err` error messages.
|
||||
|
||||
use crate::errors::{Error, ErrorKind, SourceDestError, SourceDestErrorKind};
|
||||
use std::fs::{Metadata, Permissions};
|
||||
use std::path::{Path, PathBuf};
|
||||
use tokio::io;
|
||||
mod dir_builder;
|
||||
mod file;
|
||||
mod open_options;
|
||||
mod read_dir;
|
||||
|
||||
pub use self::open_options::OpenOptions;
|
||||
pub use self::read_dir::{read_dir, DirEntry, ReadDir};
|
||||
pub use dir_builder::DirBuilder;
|
||||
pub use file::File;
|
||||
|
||||
/// Wrapper for [`tokio::fs::canonicalize`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn canonicalize(path: impl AsRef<Path>) -> io::Result<PathBuf> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::canonicalize(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::Canonicalize, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::copy`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn copy(from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<u64, io::Error> {
|
||||
let (from, to) = (from.as_ref(), to.as_ref());
|
||||
tokio::fs::copy(from, to)
|
||||
.await
|
||||
.map_err(|err| SourceDestError::build(err, SourceDestErrorKind::Copy, from, to))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::create_dir`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn create_dir(path: impl AsRef<Path>) -> io::Result<()> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::create_dir(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::CreateDir, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::create_dir_all`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn create_dir_all(path: impl AsRef<Path>) -> io::Result<()> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::create_dir_all(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::CreateDir, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::hard_link`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||
let (src, dst) = (src.as_ref(), dst.as_ref());
|
||||
tokio::fs::hard_link(src, dst)
|
||||
.await
|
||||
.map_err(|err| SourceDestError::build(err, SourceDestErrorKind::HardLink, src, dst))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::metadata`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn metadata(path: impl AsRef<Path>) -> io::Result<Metadata> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::metadata(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::Metadata, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::read`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn read(path: impl AsRef<Path>) -> io::Result<Vec<u8>> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::read(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::Read, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::read_link`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn read_link(path: impl AsRef<Path>) -> io::Result<PathBuf> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::read_link(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::ReadLink, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::read_to_string`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn read_to_string(path: impl AsRef<Path>) -> io::Result<String> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::read_to_string(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::Read, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::remove_dir`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn remove_dir(path: impl AsRef<Path>) -> io::Result<()> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::remove_dir(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::RemoveDir, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::remove_dir_all`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn remove_dir_all(path: impl AsRef<Path>) -> io::Result<()> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::remove_dir_all(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::RemoveDir, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::remove_file`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn remove_file(path: impl AsRef<Path>) -> io::Result<()> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::remove_file(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::RemoveFile, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::rename`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn rename(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
|
||||
let (from, to) = (from.as_ref(), to.as_ref());
|
||||
tokio::fs::rename(from, to)
|
||||
.await
|
||||
.map_err(|err| SourceDestError::build(err, SourceDestErrorKind::Rename, from, to))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::set_permissions`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn set_permissions(path: impl AsRef<Path>, perm: Permissions) -> io::Result<()> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::set_permissions(path, perm)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::SetPermissions, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::symlink_metadata`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn symlink_metadata(path: impl AsRef<Path>) -> io::Result<Metadata> {
|
||||
let path = path.as_ref();
|
||||
tokio::fs::symlink_metadata(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::SymlinkMetadata, path))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::symlink`].
|
||||
#[cfg(unix)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn symlink(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||
let (src, dst) = (src.as_ref(), dst.as_ref());
|
||||
tokio::fs::symlink(src, dst)
|
||||
.await
|
||||
.map_err(|err| SourceDestError::build(err, SourceDestErrorKind::Symlink, src, dst))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::symlink_dir`].
|
||||
#[cfg(windows)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn symlink(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||
let (src, dst) = (src.as_ref(), dst.as_ref());
|
||||
tokio::fs::symlink_dir(src, dst)
|
||||
.await
|
||||
.map_err(|err| SourceDestError::build(err, SourceDestErrorKind::SymlinkDir, src, dst))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::symlink_file`].
|
||||
#[cfg(windows)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn symlink_file(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
|
||||
let (src, dst) = (src.as_ref(), dst.as_ref());
|
||||
tokio::fs::symlink_file(src, dst)
|
||||
.await
|
||||
.map_err(|err| SourceDestError::build(err, SourceDestErrorKind::SymlinkFile, src, dst))
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::write`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> io::Result<()> {
|
||||
let (path, contents) = (path.as_ref(), contents.as_ref());
|
||||
tokio::fs::write(path, contents)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::Write, path))
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
use crate::errors::{Error, ErrorKind};
|
||||
use crate::tokio::File;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use tokio::fs::OpenOptions as TokioOpenOptions;
|
||||
|
||||
/// Options and flags which can be used to configure how a file is opened.
|
||||
///
|
||||
/// This is a wrapper around [`tokio::fs::OpenOptions`].
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub struct OpenOptions {
|
||||
tokio: TokioOpenOptions,
|
||||
}
|
||||
|
||||
impl OpenOptions {
|
||||
/// Creates a blank new set of options ready for configuration.
|
||||
///
|
||||
/// All options are initially set to `false`.
|
||||
///
|
||||
/// This is a wrapped version of [`tokio::fs::OpenOptions::new`]
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// use fs_err::tokio::OpenOptions;
|
||||
///
|
||||
/// let mut options = OpenOptions::new();
|
||||
/// let future = options.read(true).open("foo.txt");
|
||||
/// ```
|
||||
pub fn new() -> OpenOptions {
|
||||
OpenOptions {
|
||||
tokio: TokioOpenOptions::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::OpenOptions::read`].
|
||||
pub fn read(&mut self, read: bool) -> &mut OpenOptions {
|
||||
self.tokio.read(read);
|
||||
self
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::OpenOptions::write`].
|
||||
pub fn write(&mut self, write: bool) -> &mut OpenOptions {
|
||||
self.tokio.write(write);
|
||||
self
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::OpenOptions::append`].
|
||||
pub fn append(&mut self, append: bool) -> &mut OpenOptions {
|
||||
self.tokio.append(append);
|
||||
self
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::OpenOptions::truncate`].
|
||||
pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
|
||||
self.tokio.truncate(truncate);
|
||||
self
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::OpenOptions::create`].
|
||||
pub fn create(&mut self, create: bool) -> &mut OpenOptions {
|
||||
self.tokio.create(create);
|
||||
self
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::OpenOptions::create_new`].
|
||||
pub fn create_new(&mut self, create_new: bool) -> &mut OpenOptions {
|
||||
self.tokio.create_new(create_new);
|
||||
self
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::OpenOptions::open`].
|
||||
pub async fn open(&self, path: impl AsRef<Path>) -> io::Result<File> {
|
||||
let path = path.as_ref();
|
||||
self.tokio
|
||||
.open(path)
|
||||
.await
|
||||
.map(|f| File::from_parts(f, path))
|
||||
.map_err(|err| Error::build(err, ErrorKind::OpenFile, path))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl OpenOptions {
|
||||
/// Wrapper for [`tokio::fs::OpenOptions::mode`].
|
||||
pub fn mode(&mut self, mode: u32) -> &mut OpenOptions {
|
||||
self.tokio.mode(mode);
|
||||
self
|
||||
}
|
||||
|
||||
/// Wrapper for [`tokio::fs::OpenOptions::custom_flags`].
|
||||
pub fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
|
||||
self.tokio.custom_flags(flags);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::fs::OpenOptions> for OpenOptions {
|
||||
fn from(std: std::fs::OpenOptions) -> Self {
|
||||
OpenOptions { tokio: std.into() }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TokioOpenOptions> for OpenOptions {
|
||||
fn from(tokio: TokioOpenOptions) -> Self {
|
||||
OpenOptions { tokio }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
use crate::errors::{Error, ErrorKind};
|
||||
use std::ffi::OsString;
|
||||
use std::fs::{FileType, Metadata};
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::task::{ready, Context, Poll};
|
||||
use tokio::fs;
|
||||
|
||||
/// Wrapper for [`tokio::fs::read_dir`].
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub async fn read_dir(path: impl AsRef<Path>) -> io::Result<ReadDir> {
|
||||
let path = path.as_ref();
|
||||
let tokio = fs::read_dir(path)
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::ReadDir, path))?;
|
||||
Ok(ReadDir {
|
||||
tokio,
|
||||
path: path.to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Reads the entries in a directory.
|
||||
///
|
||||
/// This is a wrapper around [`tokio::fs::ReadDir`].
|
||||
#[derive(Debug)]
|
||||
#[must_use = "streams do nothing unless polled"]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub struct ReadDir {
|
||||
tokio: fs::ReadDir,
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
impl ReadDir {
|
||||
/// Wrapper around [`tokio::fs::ReadDir::next_entry`].
|
||||
pub async fn next_entry(&mut self) -> io::Result<Option<DirEntry>> {
|
||||
match self.tokio.next_entry().await {
|
||||
Ok(entry) => Ok(entry.map(|e| DirEntry { tokio: e })),
|
||||
Err(err) => Err(Error::build(err, ErrorKind::ReadDir, &self.path)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper around [`tokio::fs::ReadDir::poll_next_entry`].
|
||||
pub fn poll_next_entry(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<Option<DirEntry>>> {
|
||||
Poll::Ready(match ready!(self.tokio.poll_next_entry(cx)) {
|
||||
Ok(entry) => Ok(entry.map(|e| DirEntry { tokio: e })),
|
||||
Err(err) => Err(Error::build(err, ErrorKind::ReadDir, &self.path)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Entries returned by the [`ReadDir`] stream.
|
||||
///
|
||||
/// This is a wrapper around [`tokio::fs::DirEntry`].
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
|
||||
pub struct DirEntry {
|
||||
tokio: fs::DirEntry,
|
||||
}
|
||||
|
||||
impl DirEntry {
|
||||
/// Wrapper around [`tokio::fs::DirEntry::path`].
|
||||
pub fn path(&self) -> PathBuf {
|
||||
self.tokio.path()
|
||||
}
|
||||
|
||||
/// Wrapper around [`tokio::fs::DirEntry::file_name`].
|
||||
pub fn file_name(&self) -> OsString {
|
||||
self.tokio.file_name()
|
||||
}
|
||||
|
||||
/// Wrapper around [`tokio::fs::DirEntry::metadata`].
|
||||
pub async fn metadata(&self) -> io::Result<Metadata> {
|
||||
self.tokio
|
||||
.metadata()
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::Metadata, self.path()))
|
||||
}
|
||||
|
||||
/// Wrapper around [`tokio::fs::DirEntry::file_type`].
|
||||
pub async fn file_type(&self) -> io::Result<FileType> {
|
||||
self.tokio
|
||||
.file_type()
|
||||
.await
|
||||
.map_err(|err| Error::build(err, ErrorKind::Metadata, self.path()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl DirEntry {
|
||||
/// Wrapper around [`tokio::fs::DirEntry::ino`].
|
||||
pub fn ino(&self) -> u64 {
|
||||
self.tokio.ino()
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче