diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8abfb35..ce479b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,7 +54,7 @@ jobs: args: --tests -- -D warnings if: matrix.rust_version == 'stable' - - name: cargo check --features io_safety + - name: cargo check --features "io_safety" uses: actions-rs/cargo@v1 with: command: check diff --git a/CHANGELOG.md b/CHANGELOG.md index 27b1a6f..0eda0e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # fs-err Changelog +* Add `fs_err_try_exists` to `std::path::Path` via extension trait. This feature requires Rust 1.63 or later. ([#48](https://github.com/andrewhickman/fs-err/pull/48)) + ## 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)). diff --git a/Cargo.toml b/Cargo.toml index b0627e4..4f220e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,11 +14,14 @@ exclude = [".github", ".gitignore", "README.tpl"] [dependencies] tokio = { version = "1.21", optional = true, default_features = false, features = ["fs"] } +[build-dependencies] +autocfg = "1" + [dev-dependencies] serde_json = "1.0.64" [features] -# Adds I/O safety traits introduced in Rust 1.63 +# Adds I/O safety traits, introduced in Rust 1.63 io_safety = [] [package.metadata.release] diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..aaa9806 --- /dev/null +++ b/build.rs @@ -0,0 +1,7 @@ +extern crate autocfg; + +fn main() { + let ac = autocfg::new(); + // Allows `#[cfg(rustc_1_63)]` to be used in code + ac.emit_rustc_version(1, 63); +} diff --git a/src/errors.rs b/src/errors.rs index e8074b3..cbda7be 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -23,6 +23,8 @@ pub(crate) enum ErrorKind { Canonicalize, ReadLink, SymlinkMetadata, + #[allow(dead_code)] + FileExists, #[cfg(windows)] SeekRead, @@ -84,6 +86,7 @@ impl fmt::Display for Error { 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), + FileExists => write!(formatter, "failed to check file existance `{}`", path), #[cfg(windows)] SeekRead => write!(formatter, "failed to seek and read from `{}`", path), diff --git a/src/path.rs b/src/path.rs index 66dc749..33b7847 100644 --- a/src/path.rs +++ b/src/path.rs @@ -1,3 +1,5 @@ +#[allow(unused_imports)] +use crate::errors::{Error, ErrorKind}; use std::fs; use std::io; use std::path::{Path, PathBuf}; @@ -8,6 +10,9 @@ use std::path::{Path, PathBuf}; // // Because no one else can implement it, we can add methods backwards-compatibly. pub trait PathExt: crate::Sealed { + /// Wrapper for [`Path::try_exists`](https://doc.rust-lang.org/std/path/struct.Path.html#method.try_exists). + #[cfg(rustc_1_63)] + fn fs_err_try_exists(&self) -> io::Result; /// Wrapper for [`crate::metadata`]. fn fs_err_metadata(&self) -> io::Result; /// Wrapper for [`crate::symlink_metadata`]. @@ -21,6 +26,12 @@ pub trait PathExt: crate::Sealed { } impl PathExt for Path { + #[cfg(rustc_1_63)] + fn fs_err_try_exists(&self) -> io::Result { + self.try_exists() + .map_err(|source| Error::build(source, ErrorKind::FileExists, self)) + } + fn fs_err_metadata(&self) -> io::Result { crate::metadata(self) }