From 93a270e8ba0222ffddca4c344965fe36d149ee05 Mon Sep 17 00:00:00 2001 From: schneems Date: Tue, 17 Oct 2023 18:01:20 -0400 Subject: [PATCH 1/2] Implement Path::try_exists Implements the `Path::try_exists` associated function mentioned in #46. The aliased function was stabilized in 1.63 so to preserve compatibility with older Rust versions (ci targets 1.40) a new feature flag was added. --- .github/workflows/ci.yml | 4 ++-- CHANGELOG.md | 2 ++ Cargo.toml | 4 +++- src/errors.rs | 3 +++ src/path.rs | 11 +++++++++++ 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f36aab8..36c1d7d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,9 +54,9 @@ jobs: args: --tests -- -D warnings if: matrix.rust_version == 'stable' - - name: cargo check --features io_safety + - name: cargo check --features "io_safety path_try_exists" uses: actions-rs/cargo@v1 with: command: clippy - args: --features io_safety + args: --features "io_safety path_try_exists" if: matrix.rust_version == 'stable' diff --git a/CHANGELOG.md b/CHANGELOG.md index 27b1a6f..ef8d513 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 and is gated behind the `path_try_exists` feature flag. ([#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..5449c06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,9 @@ tokio = { version = "1.21", optional = true, default_features = false, features serde_json = "1.0.64" [features] -# Adds I/O safety traits introduced in Rust 1.63 +# Adds `fs_err_try_exists` to `Path`, introduced in Rust 1.6.3 +path_try_exists = [] +# Adds I/O safety traits, introduced in Rust 1.63 io_safety = [] [package.metadata.release] 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..5858cb0 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(feature = "path_try_exists")] + 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(feature = "path_try_exists")] + 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) } From 4afa6f80822300ac1e1a178108f7d3aabe964291 Mon Sep 17 00:00:00 2001 From: Richard Schneeman Date: Sun, 12 Nov 2023 10:09:49 -0600 Subject: [PATCH 2/2] Use autocfg instead of a feature for try_exists Per comments on https://github.com/andrewhickman/fs-err/pull/48 this moves from gating `try_exists` behind a feature to using `autocfg`. This is a build time library that inspects the current runtime and adds flags to the build so if a user is building with Rust 1.63 or higher then this feature will be enabled. --- .github/workflows/ci.yml | 4 ++-- CHANGELOG.md | 2 +- Cargo.toml | 5 +++-- build.rs | 7 +++++++ src/path.rs | 4 ++-- 5 files changed, 15 insertions(+), 7 deletions(-) create mode 100644 build.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 36c1d7d..ff3ed8a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,9 +54,9 @@ jobs: args: --tests -- -D warnings if: matrix.rust_version == 'stable' - - name: cargo check --features "io_safety path_try_exists" + - name: cargo check --features "io_safety" uses: actions-rs/cargo@v1 with: command: clippy - args: --features "io_safety path_try_exists" + args: --features "io_safety" if: matrix.rust_version == 'stable' diff --git a/CHANGELOG.md b/CHANGELOG.md index ef8d513..0eda0e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # fs-err Changelog -* Add `fs_err_try_exists` to `std::path::Path` via extension trait. This feature requires Rust 1.63 or later and is gated behind the `path_try_exists` feature flag. ([#48](https://github.com/andrewhickman/fs-err/pull/48)) +* 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 diff --git a/Cargo.toml b/Cargo.toml index 5449c06..4f220e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,12 +14,13 @@ 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 `fs_err_try_exists` to `Path`, introduced in Rust 1.6.3 -path_try_exists = [] # Adds I/O safety traits, introduced in Rust 1.63 io_safety = [] 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/path.rs b/src/path.rs index 5858cb0..33b7847 100644 --- a/src/path.rs +++ b/src/path.rs @@ -11,7 +11,7 @@ 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(feature = "path_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; @@ -26,7 +26,7 @@ pub trait PathExt: crate::Sealed { } impl PathExt for Path { - #[cfg(feature = "path_try_exists")] + #[cfg(rustc_1_63)] fn fs_err_try_exists(&self) -> io::Result { self.try_exists() .map_err(|source| Error::build(source, ErrorKind::FileExists, self))