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

fs: add support for DirBuilder and DirBuilderExt #2524

Merged
merged 6 commits into from
May 21, 2020

Conversation

shkurski
Copy link
Contributor

@shkurski shkurski commented May 12, 2020

Motivation

tokio doesn't have an asynchronous version of std::fs::DirBuilder yet.
This PR adds support for std::fs::DirBuilder and implementation for the std::os::unix::fs::DirBuilderExt trait.

Solution

The initial idea was to implement a thin wrapper around an internally
held std::fs::DirBuilder instance. This, however, didn't work due to
std::fs::DirBuilder not having Copy/Clone traits implemented, which
was necessary for constructing an instance to move-capture it into a
closure.

Instead, we have mirrored the std::fs::DirBuilder configuration by storing
the recursive and (unix-only) mode parameters locally, which were then
used to construct the std::fs::DirBuilder instance on-the-fly.

The (unix-only) DirBuilderExt trait has been implemented in-place
within the dir_builder crate. Despite it might have looked better to
have it separated somewhere in ../fs/os/unix, I haven't found a clean
and idiomatic way to do so (due to Rust's "orphan rules"). I'd be glad
to hear the propositions in case someone sees a way for this to be
further simplified.

Edit: force-pushed immediately after the initial commit was made.
Hope it was quick enough to not break any local repo's.

Fixes: #2369

The initial idea was to implement  a thin wrapper  around an internally
held `std::fs::DirBuilder` instance.  This, however, didn't work due to
`std::fs::DirBuilder` not having a Copy/Clone traits implemented, which
are necessary  for constructing an instance to move-capture it  into  a
closure.

Instead,  we mirror `std::fs::DirBuilder` configuration by  storing the
`recursive` and (unix-only) `mode`  parameters locally,  which are then
used to construct an `std::fs::DirBuilder` instance on-the-fly.

The (unix-only) `DirBuilderExt` trait  has  been  implemented  in-place
within the `dir_builder` create. Despite it might have looked better to
have it separated somewhere in `../fs/os/unix`, I haven't found a clean
and idiomatic way to do so (due to Rust's "orphan rules").  I'd be glad
to hear  the propositions  in case someone  sees  a  way for this to be
further simplified.

Fixes: tokio-rs#2369
Copy link
Contributor

@Darksonn Darksonn left a comment

Choose a reason for hiding this comment

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

Thank you for the PR!

For the same reason as described in #2515, we should define our own extension trait instead of using the one from std.

Besides that I have a few documentation comments, and some comments on the use of #[cfg(unix)]. These are nothing major, and the PR looks pretty good in general 👍

/// A builder for creating directories in various manners.
///
/// Additional Unix-specific options are available via importing the
/// [os::unix::fs::DirBuilderExt] trait.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we change the link text to [`DirBuilderExt`]? Note that the link is broken.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines 14 to 15
/// [os::unix::fs::DirBuilderExt]: ../os/unix/fs/trait.DirBuilderExt.html
/// [std::fs::DirBuilder]: https://doc.rust-lang.org/std/fs/struct.DirBuilder.html
Copy link
Contributor

Choose a reason for hiding this comment

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

This should use intra-rustdoc links, so that broken links are automatically detected.

Suggested change
/// [os::unix::fs::DirBuilderExt]: ../os/unix/fs/trait.DirBuilderExt.html
/// [std::fs::DirBuilder]: https://doc.rust-lang.org/std/fs/struct.DirBuilder.html
/// [os::unix::fs::DirBuilderExt]: crate::os::unix::fs::DirBuilderExt
/// [std::fs::DirBuilder]: std::fs::DirBuilder

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines 42 to 46
#[cfg(not(unix))]
let builder = DirBuilder { recursive: false };

#[cfg(unix)]
let builder = DirBuilder {
Copy link
Contributor

Choose a reason for hiding this comment

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

We can just use the Default impl here.

pub fn new() -> Self {
    Default::default()
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you, switched to the Default impl.

tokio/src/fs/dir_builder.rs Show resolved Hide resolved
Comment on lines 357 to 364
macro_rules! cfg_unix {
($($item:item)*) => {
$(
#[cfg(unix)]
$item
)*
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

We use #[cfg(unix)] everywhere else in the codebase. Maybe adding this cfg_* makes sense, but I would rather want it in its own PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

/// Additional Unix-specific options are available via importing the
/// [os::unix::fs::DirBuilderExt] trait.
///
/// This is a specialized version of [`std::fs::DirBuilder`] for usage from
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// This is a specialized version of [`std::fs::DirBuilder`] for usage from
/// This is a specialized version of [`std::fs::DirBuilder`] for usage on

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! Fixed

@Darksonn Darksonn added A-tokio Area: The main tokio crate C-enhancement Category: A PR with an enhancement or bugfix. M-fs Module: tokio/fs labels May 12, 2020
This commit removes the previously implemented std::os::unix::fs::DirBuilderExt
trait from tokio::fs::DirBuilder. Additionally, the `cfg_unix` macro  has  been
dropped and the code has been simplified based on the review.
@shkurski
Copy link
Contributor Author

shkurski commented May 12, 2020

For the same reason as described in #2515, we should define our own extension trait instead of using the one from std.

Thanks for the review 👍
I've implemented our own extension trait and addressed your comments.

Copy link
Contributor

@Darksonn Darksonn left a comment

Choose a reason for hiding this comment

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

This looks good to me. 👍

Copy link
Contributor

@Darksonn Darksonn left a comment

Choose a reason for hiding this comment

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

I was going through the list of PRs and noticed this link.

Comment on lines 3 to 5
/// Unix-specific extensions to [`DirBuilderExt`].
///
/// [crate::fs::os::unix::DirBuilderExt]: DirBuilderExt
Copy link
Contributor

Choose a reason for hiding this comment

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

This link seems off. Shouldn't it link to DirBuilder?

@Darksonn Darksonn merged commit 8fda5f1 into tokio-rs:master May 21, 2020
jensim pushed a commit to jensim/tokio that referenced this pull request Jun 7, 2020
The initial idea was to implement  a thin wrapper  around an internally
held `std::fs::DirBuilder` instance.  This, however, didn't work due to
`std::fs::DirBuilder` not having a Copy/Clone traits implemented, which
are necessary  for constructing an instance to move-capture it  into  a
closure.

Instead,  we mirror `std::fs::DirBuilder` configuration by  storing the
`recursive` and (unix-only) `mode`  parameters locally,  which are then
used to construct an `std::fs::DirBuilder` instance on-the-fly.

This commit also mirrors the (unix-only) DirBuilderExt trait from std.

Fixes: tokio-rs#2369
hawkw added a commit that referenced this pull request Jul 20, 2020
- docs: misc improvements (#2572, #2658, #2663, #2656, #2647, #2630, #2487, #2621,
  #2624, #2600, #2623, #2622, #2577, #2569, #2589, #2575, #2540, #2564, #2567,
  #2520, #2521, #2572, #2493)
- rt: allow calls to `block_on` inside calls to `block_in_place` that are
  themselves inside `block_on` (#2645)
- net: fix non-portable behavior when dropping `TcpStream` `OwnedWriteHalf` (#2597)
- io: improve stack usage by allocating large buffers on directly on the heap
  (#2634)
- io: fix unsound pin projection in `AsyncReadExt::read_buf` and
  `AsyncWriteExt::write_buf` (#2612)
- io: fix unnecessary zeroing for `AsyncRead` implementors (#2525)
- io: Fix `BufReader` not correctly forwarding `poll_write_buf` (#2654)

- coop: returning `Poll::Pending` no longer decrements the task budget (#2549)

- io: little-endian variants of `AsyncReadExt` and `AsyncWriteExt` methods
  (#1915)
- io: fix panic in `AsyncReadExt::read_line` (#2541)
- task: add [`tracing`] instrumentation to spawned tasks (#2655)
- sync: allow unsized types in `Mutex` and `RwLock` (via `default` constructors)
  (#2615)
- net: add `ToSocketAddrs` implementation for `&[SocketAddr]` (#2604)
- fs: add `OpenOptionsExt` for `OpenOptions` (#2515)
- fs: add `DirBuilder` (#2524)

[`tracing`]: https://crates.io/crates/tracing

Signed-off-by: Eliza Weisman <[email protected]>
hawkw added a commit that referenced this pull request Jul 22, 2020
# 0.2.22 (July 2!, 2020)

### Fixes
- docs: misc improvements (#2572, #2658, #2663, #2656, #2647, #2630, #2487, #2621,
  #2624, #2600, #2623, #2622, #2577, #2569, #2589, #2575, #2540, #2564, #2567,
  #2520, #2521, #2493)
- rt: allow calls to `block_on` inside calls to `block_in_place` that are
  themselves inside `block_on` (#2645)
- net: fix non-portable behavior when dropping `TcpStream` `OwnedWriteHalf` (#2597)
- io: improve stack usage by allocating large buffers on directly on the heap
  (#2634)
- io: fix unsound pin projection in `AsyncReadExt::read_buf` and
  `AsyncWriteExt::write_buf` (#2612)
- io: fix unnecessary zeroing for `AsyncRead` implementors (#2525)
- io: Fix `BufReader` not correctly forwarding `poll_write_buf` (#2654)
- io: fix panic in `AsyncReadExt::read_line` (#2541)

### Changes
- coop: returning `Poll::Pending` no longer decrements the task budget (#2549)

### Added
- io: little-endian variants of `AsyncReadExt` and `AsyncWriteExt` methods
  (#1915)
- task: add [`tracing`] instrumentation to spawned tasks (#2655)
- sync: allow unsized types in `Mutex` and `RwLock` (via `default` constructors)
  (#2615)
- net: add `ToSocketAddrs` implementation for `&[SocketAddr]` (#2604)
- fs: add `OpenOptionsExt` for `OpenOptions` (#2515)
- fs: add `DirBuilder` (#2524)

[`tracing`]: https://crates.io/crates/tracing

Signed-off-by: Eliza Weisman <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-enhancement Category: A PR with an enhancement or bugfix. M-fs Module: tokio/fs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

consider add DirBuilder and implement std::os::unix::fs::DirBuilderExt
2 participants