Fix docs for `fs::rename()`
- Dominant language
- Rust
- Stars
- 4.1k
- Forks
- 339
- PR merge metrics
- No merged PRs in 30d
Description
Found another minor documentation error. Yay :)
Maybe I'm missing something, but [`fs::rename()`](https://docs.rs/async-std/latest/async_std/fs/fn.rename.html)'s docs also have the wrong behavior documented:
>If a file or directory already exists at the target location, it will be overwritten by this operation.
However, async-std's `rename()` uses std's [`rename()`](https://doc.rust-lang.org/std/fs/fn.rename.html) [internally](https://docs.rs/async-std/latest/src/async_std/fs/rename.rs.html#39), which currently MAY return an error if `to` exists:
>replacing the original **_file_** if to already exists.
>[**Platform-specific behavior**](https://doc.rust-lang.org/std/fs/fn.rename.html#platform-specific-behavior)
>
>This function currently corresponds to the `rename` function on Unix and the `MoveFileEx` function with the `MOVEFILE_REPLACE_EXISTING` flag on Windows.
>
>Because of this, the behavior when both `from` and `to` exist differs. On Unix, **_if `from` is a directory, `to` must also be an (empty) directory. If `from` is not a directory, `to` must also be not a directory_**. In contrast, on Windows, `from` can be anything, but **_`to` must not be a directory_**.
Therefore, the simple statement
> If a file or directory already exists at the target location, it will be overwritten by this operation.
does not cover the cases where it WILL return an error, which is:
**Unix (and Linux):**
- `from` and `to` is an existing directory and a file, or a file and a directory respectively.
- `from` and `to` are both directories, but `to` is not empty.
**Windows**
- `from` is a existing directory.
This behavior can be demonstrated with the following code:
```rust
fn main() -> io::Result<()> {
async_std::task::block_on(async {
let from = Path::new("./foo");
//Create some directories...
fs::create_dir_all(from).await?;
fs::create_dir_all("./bar/baz").await?;
//This should work... or does it?
fs::rename(from, "./bar").await
})
}
```
(Note that this uses `fs::create_dir_all()` to avoid returning an error if the directories already exist, see #1051)
Running the above code prints
```
Error: Custom { kind: PermissionDenied, error: VerboseError { source: Os { code: 5, kind: PermissionDenied, message: "Access is denied." }, message: "could not rename `./foo` to `./bar`" } }
```
for Windows, and
```
Error: Custom { kind: DirectoryNotEmpty, error: VerboseError { source: Os { code: 39, kind: DirectoryNotEmpty, message: "Directory not empty" }, message: "could not rename `./foo` to `./bar`" } }
```
for Linux.
Contributor guide
Assessment
This issue has not been assessed yet.