Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Path::try_exists #48

Merged
merged 3 commits into from
Nov 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)).
Expand Down
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure best practice on features. Other things I considered include:

Adding an all feature that loads all features:

all = ["path_try_exists", "io_safety"]

Alternatively making a feature named 1_63 that would enable all features on 1.63+.

1_63 = ["path_try_exists", "io_safety"]

io_safety = []

[package.metadata.release]
Expand Down
7 changes: 7 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -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);
}
3 changes: 3 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub(crate) enum ErrorKind {
Canonicalize,
ReadLink,
SymlinkMetadata,
#[allow(dead_code)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to put the method behind a feature flag, I needed to get clippy to not complain about this unused variant. Maybe there's a better way or pattern.

FileExists,

#[cfg(windows)]
SeekRead,
Expand Down Expand Up @@ -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),
Expand Down
11 changes: 11 additions & 0 deletions src/path.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#[allow(unused_imports)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import is only needed when path_try_exists feature is enabled. Without the allow unused imports clippy generates a warning. Maybe there's a better way to avoid it.

In this case I think it affects the whole file, not just this one import. Which is not ideal

use crate::errors::{Error, ErrorKind};
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
Expand All @@ -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<bool>;
/// Wrapper for [`crate::metadata`].
fn fs_err_metadata(&self) -> io::Result<fs::Metadata>;
/// Wrapper for [`crate::symlink_metadata`].
Expand All @@ -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<bool> {
self.try_exists()
.map_err(|source| Error::build(source, ErrorKind::FileExists, self))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weirdly enough, try_exists on Path is stabilized by fs::try_exists is not. I couldn't follow the same pattern used by the rest of the associated trait functions.

}

fn fs_err_metadata(&self) -> io::Result<fs::Metadata> {
crate::metadata(self)
}
Expand Down
Loading