chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

1
vendor/fs_extra/.cargo-checksum.json vendored Normal file
View File

@@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"26c21e2352b5e99dbfb29e495f8e9963c018f820ecb7a05977ebc88c0523c6bc","Cargo.toml":"84508fee5e8b314e18c1fab6d601975bff0b0897b9dbfe1fbf1451efe71a4449","Cargo.toml.orig":"66f2e47ab7856c64bb1d160e6a313956dd75c0230a3e5695731cba3d417bbd8a","LICENSE":"251ea8ccb1205ce5fa847d6e264d6b6753af62de2cecf2fd9abc0eb02c7c83fc","README.md":"6c72565b5c7e12dcdb4dbaca0034fd5c9721f38bf5952fd96c3947571df26db0","src/dir.rs":"888a2defde401d8fb1da5aa18b58efe210a0fdd9e74bdfa6867c3aa188de0b40","src/error.rs":"7306cb0e85081d7ef4b2d59cf5f068df7585c2d0ce3b5219c7c9448c20801a61","src/file.rs":"e6eefb1b91503b834571f8d27badbca8dac50c50f23d43b03277a52ed2c3edbb","src/lib.rs":"cb4ae7a8080a6de2cf99aae2338486cf777bb300f7d2082d98238b4eb746648c","tests/dir.rs":"20bda4edbaa23397e83361586e5742360fcbbec8f5bf46c9c208ee7b05a13db7","tests/file.rs":"06829b2db83e2805c87b83862c75cb1016ce7d12e5d8236eefbe39ffa16fa553","tests/lib.rs":"567eb582e8e1524b3f6c79cd8683fdd7b11cbd1ba5461b319cf2ffec211eb789"},"package":"42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"}

5
vendor/fs_extra/.cargo_vcs_info.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"git": {
"sha1": "1754296075e7cc4a25feaa876a3f4b9daccc0b98"
}
}

26
vendor/fs_extra/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,26 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
edition = "2018"
name = "fs_extra"
version = "1.3.0"
authors = ["Denis Kurilenko <webdesus@gmail.com>"]
include = ["**/*.rs", "Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md"]
description = "Expanding std::fs and std::io. Recursively copy folders with information about process and much more."
homepage = "https://github.com/webdesus/fs_extra"
documentation = "https://docs.rs/fs_extra"
keywords = ["filesystem", "recursion", "copy", "dir", "file"]
license = "MIT"
repository = "https://github.com/webdesus/fs_extra"
[dependencies]

21
vendor/fs_extra/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Denis Kurilenko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

134
vendor/fs_extra/README.md vendored Normal file
View File

@@ -0,0 +1,134 @@
# fs_extra
A Rust library that provides additional functionality not present in [`std::fs`](https://doc.rust-lang.org/std/fs/index.html).
[![Build Status](https://travis-ci.org/webdesus/fs_extra.svg)](https://travis-ci.org/webdesus/fs_extra)
[![Crates.io Status](https://img.shields.io/crates/v/fs_extra.svg)](https://crates.io/crates/fs_extra)
[![Docs](https://docs.rs/fs_extra/badge.svg)](https://docs.rs/fs_extra)
[Documentation](https://docs.rs/fs_extra)
[Migrations to 1.x.x version](https://github.com/webdesus/fs_extra/wiki/Migrations-to-1.x.x-version)
## Key features:
* Copy files (optionally with information about the progress).
* Copy directories recursively (optionally with information about the progress).
* Move files (optionally with information about the progress).
* Move directories recursively (optionally with information about the progress).
* A single method for create and write `String` content in file.
* A single method for open and read `String` content from file.
* Get folder size
* Get collection of directory entries
## Functions:
| Function | Description |
| ------------- | ------------- |
| [fs_extra::copy_items](https://docs.rs/fs_extra/*/fs_extra/fn.copy_items.html) | Recursively copies files and directories from one location to another |
| [fs_extra::copy_items_with_progress](https://docs.rs/fs_extra/*/fs_extra/fn.copy_items_with_progress.html) | Recursively copies files and directories from one location to another with information about progress |
| [fs_extra::move_items](https://docs.rs/fs_extra/*/fs_extra/fn.move_items.html) | Recursively moves files and directories from one location to another |
| [fs_extra::move_items_with_progress](https://docs.rs/fs_extra/*/fs_extra/fn.move_items_with_progress.html) | Recursively moves files and directories from one location to another with information about progress |
| [fs_extra::remove_items](https://docs.rs/fs_extra/*/fs_extra/fn.remove_items.html) | Removes files or directories |
| [fs_extra::file::copy](https://docs.rs/fs_extra/*/fs_extra/file/fn.copy.html) | Copies the contents of one file to another |
| [fs_extra::file::copy_with_progress](https://docs.rs/fs_extra/*/fs_extra/file/fn.copy_with_progress.html) | Copies the contents of one file to another with information about progress |
| [fs_extra::file::move_file](https://docs.rs/fs_extra/*/fs_extra/file/fn.move_file.html) | Moves a file from one location to another |
| [fs_extra::file::move_file_with_progress](https://docs.rs/fs_extra/*/fs_extra/file/fn.move_file_with_progress.html) | Moves a file from one location to another with information about progress |
| [fs_extra::file::remove](https://docs.rs/fs_extra/*/fs_extra/file/fn.remove.html) | Removes a file |
| [fs_extra::file::read_to_string](https://docs.rs/fs_extra/*/fs_extra/file/fn.read_to_string.html) | Reads file content into a `String` |
| [fs_extra::file::write_all](https://docs.rs/fs_extra/*/fs_extra/file/fn.write_all.html) | Writes `String` content to a file |
| [fs_extra::dir::create](https://docs.rs/fs_extra/*/fs_extra/dir/fn.create.html) | Creates a new, empty directory at the given path |
| [fs_extra::dir::create_all](https://docs.rs/fs_extra/*/fs_extra/dir/fn.create_all.html) | Recursively creates a directory and all of its parent components if they are missing |
| [fs_extra::dir::copy](https://docs.rs/fs_extra/*/fs_extra/dir/fn.copy.html) | Recursively copies the directory contents from one location to another |
| [fs_extra::dir::copy_with_progress](https://docs.rs/fs_extra/*/fs_extra/dir/fn.copy_with_progress.html) | Recursively copies the directory contents from one location to another with information about progress |
| [fs_extra::dir::move_dir](https://docs.rs/fs_extra/*/fs_extra/dir/fn.move_dir.html) | Moves directory contents from one location to another |
| [fs_extra::dir::move_dir_with_progress](https://docs.rs/fs_extra/*/fs_extra/dir/fn.move_dir_with_progress.html) | Moves directory contents from one location to another with information about progress |
| [fs_extra::dir::remove](https://docs.rs/fs_extra/*/fs_extra/dir/fn.remove.html) | Removes directory |
| [fs_extra::dir::get_size](https://docs.rs/fs_extra/*/fs_extra/dir/fn.get_size.html) | Returns the size of the file or directory |
| [fs_extra::dir::get_dir_content](https://docs.rs/fs_extra/*/fs_extra/dir/fn.get_dir_content.html) | Gets details such as the size and child items of a directory |
| [fs_extra::dir::get_dir_content2](https://docs.rs/fs_extra/*/fs_extra/dir/fn.get_dir_content2.html) | Gets details such as the size and child items of a directory using specified settings |
| [fs_extra::dir::get_details_entry](https://docs.rs/fs_extra/*/fs_extra/dir/fn.get_details_entry.html) | Gets attributes of a directory entry |
| [fs_extra::dir::ls](https://docs.rs/fs_extra/*/fs_extra/dir/fn.ls.html) | Gets attributes of directory entries in a directory |
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
fs_extra = "1.3.0"
```
## Examples
The following example shows how to copy a directory recursively and display progress. First a source directory `./temp/dir` containing file `test1.txt` and a subdirectory `sub` is createad with `sub` itself having a file `test2.txt`. `./temp/dir` and all contents are then copied out to `./out/dir`.
```rust
use std::path::Path;
use std::{thread, time};
use std::sync::mpsc::{self, TryRecvError};
extern crate fs_extra;
use fs_extra::dir::*;
use fs_extra::error::*;
fn example_copy() -> Result<()> {
let path_from = Path::new("./temp");
let path_to = path_from.join("out");
let test_folder = path_from.join("test_folder");
let dir = test_folder.join("dir");
let sub = dir.join("sub");
let file1 = dir.join("file1.txt");
let file2 = sub.join("file2.txt");
create_all(&sub, true)?;
create_all(&path_to, true)?;
fs_extra::file::write_all(&file1, "content1")?;
fs_extra::file::write_all(&file2, "content2")?;
assert!(dir.exists());
assert!(sub.exists());
assert!(file1.exists());
assert!(file2.exists());
let mut options = CopyOptions::new();
options.buffer_size = 1;
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let handler = |process_info: TransitProcess| {
tx.send(process_info).unwrap();
thread::sleep(time::Duration::from_millis(500));
fs_extra::dir::TransitProcessResult::ContinueOrAbort
};
copy_with_progress(&test_folder, &path_to, &options, handler).unwrap();
});
loop {
match rx.try_recv() {
Ok(process_info) => {
println!("{} of {} bytes",
process_info.copied_bytes,
process_info.total_bytes);
}
Err(TryRecvError::Disconnected) => {
println!("finished");
break;
}
Err(TryRecvError::Empty) => {}
}
}
Ok(())
}
fn main() {
example_copy();
}
```

1398
vendor/fs_extra/src/dir.rs vendored Normal file

File diff suppressed because it is too large Load Diff

158
vendor/fs_extra/src/error.rs vendored Normal file
View File

@@ -0,0 +1,158 @@
use std::error::Error as StdError;
use std::ffi::OsString;
use std::fmt;
use std::io::Error as IoError;
use std::io::ErrorKind as IoErrorKind;
use std::path::StripPrefixError;
/// A list specifying general categories of fs_extra error.
#[derive(Debug)]
pub enum ErrorKind {
/// An entity was not found.
NotFound,
/// The operation lacked the necessary privileges to complete.
PermissionDenied,
/// An entity already exists.
AlreadyExists,
/// This operation was interrupted.
Interrupted,
/// Path does not a directory.
InvalidFolder,
/// Path does not a file.
InvalidFile,
/// Invalid file name.
InvalidFileName,
/// Invalid path.
InvalidPath,
/// Any I/O error.
Io(IoError),
/// Any StripPrefix error.
StripPrefix(StripPrefixError),
/// Any OsString error.
OsString(OsString),
/// Any fs_extra error not part of this list.
Other,
}
impl ErrorKind {
fn as_str(&self) -> &str {
match *self {
ErrorKind::NotFound => "entity not found",
ErrorKind::PermissionDenied => "permission denied",
ErrorKind::AlreadyExists => "entity already exists",
ErrorKind::Interrupted => "operation interrupted",
ErrorKind::Other => "other os error",
ErrorKind::InvalidFolder => "invalid folder error",
ErrorKind::InvalidFile => "invalid file error",
ErrorKind::InvalidFileName => "invalid file name error",
ErrorKind::InvalidPath => "invalid path error",
ErrorKind::Io(_) => "Io error",
ErrorKind::StripPrefix(_) => "Strip prefix error",
ErrorKind::OsString(_) => "OsString error",
}
}
}
/// A specialized Result type for fs_extra operations.
///
/// This typedef is generally used to avoid writing out fs_extra::Error directly
/// and is otherwise a direct mapping to Result.
///
///#Examples
///
/// ```rust,ignore
/// extern crate fs_extra;
/// use fs_extra::dir::create;
///
///fn get_string() -> io::Result<()> {
///
/// create("test_dir")?;
///
/// Ok(())
/// }
/// ```
pub type Result<T> = ::std::result::Result<T, Error>;
/// The error type for fs_extra operations with files and folder.
///
/// Errors mostly originate from the underlying OS, but custom instances of
/// `Error` can be created with crafted error messages and a particular value of
/// [`ErrorKind`].
///
/// [`ErrorKind`]: enum.ErrorKind.html
#[derive(Debug)]
pub struct Error {
/// Type error
pub kind: ErrorKind,
message: String,
}
impl Error {
/// Create a new fs_extra error from a kind of error error as well as an arbitrary error payload.
///
///#Examples
/// ```rust,ignore
///
/// extern crate fs_extra;
/// use fs_extra::error::{Error, ErrorKind};
///
/// errors can be created from strings
/// let custom_error = Error::new(ErrorKind::Other, "Other Error!");
/// // errors can also be created from other errors
/// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
///
/// ```
pub fn new(kind: ErrorKind, message: &str) -> Error {
Error {
kind,
message: message.to_string(),
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl StdError for Error {
fn description(&self) -> &str {
self.kind.as_str()
}
}
impl From<StripPrefixError> for Error {
fn from(err: StripPrefixError) -> Error {
Error::new(
ErrorKind::StripPrefix(err),
"StripPrefixError. Look inside for more details",
)
}
}
impl From<OsString> for Error {
fn from(err: OsString) -> Error {
Error::new(
ErrorKind::OsString(err),
"OsString. Look inside for more details",
)
}
}
impl From<IoError> for Error {
fn from(err: IoError) -> Error {
let err_kind: ErrorKind;
match err.kind() {
IoErrorKind::NotFound => err_kind = ErrorKind::NotFound,
IoErrorKind::PermissionDenied => err_kind = ErrorKind::PermissionDenied,
IoErrorKind::AlreadyExists => err_kind = ErrorKind::AlreadyExists,
IoErrorKind::Interrupted => err_kind = ErrorKind::Interrupted,
IoErrorKind::Other => err_kind = ErrorKind::Other,
_ => {
err_kind = ErrorKind::Io(err);
return Error::new(err_kind, "Io error. Look inside err_kind for more details.");
}
}
Error::new(err_kind, &err.to_string())
}
}

413
vendor/fs_extra/src/file.rs vendored Normal file
View File

@@ -0,0 +1,413 @@
use crate::error::{Error, ErrorKind, Result};
use std;
use std::fs::{remove_file, File};
use std::io::{Read, Write};
use std::path::Path;
// Options and flags which can be used to configure how a file will be copied or moved.
pub struct CopyOptions {
/// Sets the option true for overwrite existing files.
pub overwrite: bool,
/// Sets the option true for skip existing files.
pub skip_exist: bool,
/// Sets buffer size for copy/move work only with receipt information about process work.
pub buffer_size: usize,
}
impl CopyOptions {
/// Initialize struct CopyOptions with default value.
///
/// ```rust,ignore
///
/// overwrite: false
///
/// skip_exist: false
///
/// buffer_size: 64000 //64kb
/// ```
pub fn new() -> CopyOptions {
CopyOptions {
overwrite: false,
skip_exist: false,
buffer_size: 64000, //64kb
}
}
/// Sets the option true for overwrite existing files.
pub fn overwrite(mut self, overwrite: bool) -> Self {
self.overwrite = overwrite;
self
}
/// Sets the option true for skip existing files.
pub fn skip_exist(mut self, skip_exist: bool) -> Self {
self.skip_exist = skip_exist;
self
}
/// Sets buffer size for copy/move work only with receipt information about process work.
pub fn buffer_size(mut self, buffer_size: usize) -> Self {
self.buffer_size = buffer_size;
self
}
}
impl Default for CopyOptions {
fn default() -> Self {
CopyOptions::new()
}
}
/// A structure which stores information about the current status of a file that's copied or moved. .
pub struct TransitProcess {
/// Copied bytes on this time.
pub copied_bytes: u64,
/// All the bytes which should to copy or move.
pub total_bytes: u64,
}
/// Copies the contents of one file to another. This function will also copy the permission
/// bits of the original file to the destination file.
///
/// # Errors
///
/// This function will return an error in the following situations, but is not limited to just
/// these cases:
///
/// * This `from` path is not a file.
/// * This `from` file does not exist.
/// * The current process does not have the permission to access `from` or write `to`.
///
/// # Example
///
/// ```rust,ignore
/// extern crate fs_extra;
/// use fs_extra::file::copy;
///
/// let options = CopyOptions::new(); //Initialize default values for CopyOptions
/// copy("dir1/foo.txt", "dir2/bar.txt", &options)?; // Copy dir1/foo.txt to dir2/bar.txt
///
/// ```
pub fn copy<P, Q>(from: P, to: Q, options: &CopyOptions) -> Result<u64>
where
P: AsRef<Path>,
Q: AsRef<Path>,
{
let from = from.as_ref();
if !from.exists() {
if let Some(msg) = from.to_str() {
let msg = format!("Path \"{}\" does not exist or you don't have access!", msg);
err!(&msg, ErrorKind::NotFound);
}
err!(
"Path does not exist or you don't have access!",
ErrorKind::NotFound
);
}
if !from.is_file() {
if let Some(msg) = from.to_str() {
let msg = format!("Path \"{}\" is not a file!", msg);
err!(&msg, ErrorKind::InvalidFile);
}
err!("Path is not a file!", ErrorKind::InvalidFile);
}
if !options.overwrite && to.as_ref().exists() {
if options.skip_exist {
return Ok(0);
}
if let Some(msg) = to.as_ref().to_str() {
let msg = format!("Path \"{}\" exists", msg);
err!(&msg, ErrorKind::AlreadyExists);
}
}
Ok(std::fs::copy(from, to)?)
}
/// Copies the contents of one file to another file with information about progress.
/// This function will also copy the permission bits of the original file to the
/// destination file.
///
/// # Errors
///
/// This function will return an error in the following situations, but is not limited to just
/// these cases:
///
/// * This `from` path is not a file.
/// * This `from` file does not exist.
/// * The current process does not have the permission to access `from` or write `to`.
///
/// # Example
/// ```rust,ignore
/// extern crate fs_extra;
/// use fs_extra::file::copy_with_progress;
///
/// let options = CopyOptions::new(); //Initialize default values for CopyOptions
/// let handle = |process_info: TransitProcess| println!("{}", process_info.total_bytes);
///
/// // Copy dir1/foo.txt to dir2/foo.txt
/// copy_with_progress("dir1/foo.txt", "dir2/foo.txt", &options, handle)?;
///
/// ```
pub fn copy_with_progress<P, Q, F>(
from: P,
to: Q,
options: &CopyOptions,
mut progress_handler: F,
) -> Result<u64>
where
P: AsRef<Path>,
Q: AsRef<Path>,
F: FnMut(TransitProcess),
{
let from = from.as_ref();
if !from.exists() {
if let Some(msg) = from.to_str() {
let msg = format!("Path \"{}\" does not exist or you don't have access!", msg);
err!(&msg, ErrorKind::NotFound);
}
err!(
"Path does not exist or you don't have access!",
ErrorKind::NotFound
);
}
if !from.is_file() {
if let Some(msg) = from.to_str() {
let msg = format!("Path \"{}\" is not a file!", msg);
err!(&msg, ErrorKind::InvalidFile);
}
err!("Path is not a file!", ErrorKind::InvalidFile);
}
if !options.overwrite && to.as_ref().exists() {
if options.skip_exist {
return Ok(0);
}
if let Some(msg) = to.as_ref().to_str() {
let msg = format!("Path \"{}\" exists", msg);
err!(&msg, ErrorKind::AlreadyExists);
}
}
let mut file_from = File::open(from)?;
let mut buf = vec![0; options.buffer_size];
let file_size = file_from.metadata()?.len();
let mut copied_bytes: u64 = 0;
let mut file_to = File::create(to)?;
while !buf.is_empty() {
match file_from.read(&mut buf) {
Ok(0) => break,
Ok(n) => {
let written_bytes = file_to.write(&buf[..n])?;
if written_bytes != n {
err!("Couldn't write the whole buffer to file", ErrorKind::Other);
}
copied_bytes += n as u64;
let data = TransitProcess {
copied_bytes,
total_bytes: file_size,
};
progress_handler(data);
}
Err(ref e) if e.kind() == ::std::io::ErrorKind::Interrupted => {}
Err(e) => return Err(::std::convert::From::from(e)),
}
}
Ok(file_size)
}
/// Moves a file from one place to another. This function will also copy the permission
/// bits of the original file to the destination file.
///
/// # Errors
///
/// This function will return an error in the following situations, but is not limited to just
/// these cases:
///
/// * This `from` path is not a file.
/// * This `from` file does not exist.
/// * The current process does not have the permission to access `from` or write `to`.
///
/// # Example
/// ```rust,ignore
/// extern crate fs_extra;
/// use fs_extra::file::move_file;
///
/// let options = CopyOptions::new(); //Initialize default values for CopyOptions
/// move_file("dir1/foo.txt", "dir2/foo.txt", &options)?; // Move dir1/foo.txt to dir2/foo.txt
///
/// ```
pub fn move_file<P, Q>(from: P, to: Q, options: &CopyOptions) -> Result<u64>
where
P: AsRef<Path>,
Q: AsRef<Path>,
{
let mut is_remove = true;
if options.skip_exist && to.as_ref().exists() && !options.overwrite {
is_remove = false;
}
let result = copy(&from, to, options)?;
if is_remove {
remove(from)?;
}
Ok(result)
}
/// Moves a file from one place to another with information about progress.
/// This function will also copy the permission bits of the original file to the
/// destination file.
///
/// # Errors
///
/// This function will return an error in the following situations, but is not limited to just
/// these cases:
///
/// * This `from` path is not a file.
/// * This `from` file does not exist.
/// * The current process does not have the permission to access `from` or write `to`.
///
/// # Example
/// ```rust,ignore
/// extern crate fs_extra;
/// use fs_extra::file::move_file;
///
/// let options = CopyOptions::new(); //Initialize default values for CopyOptions
/// let handle = |process_info: TransitProcess| println!("{}", process_info.total_bytes);
///
/// // Move dir1/foo.txt to dir2/foo.txt
/// move_file("dir1/foo.txt", "dir2/foo.txt", &options, handle)?;
///
/// ```
pub fn move_file_with_progress<P, Q, F>(
from: P,
to: Q,
options: &CopyOptions,
progress_handler: F,
) -> Result<u64>
where
P: AsRef<Path>,
Q: AsRef<Path>,
F: FnMut(TransitProcess),
{
let mut is_remove = true;
if options.skip_exist && to.as_ref().exists() && !options.overwrite {
is_remove = false;
}
let result = copy_with_progress(&from, to, options, progress_handler)?;
if is_remove {
remove(from)?;
}
Ok(result)
}
/// Removes a file from the filesystem.
///
/// # Errors
///
/// This function will return an error in the following situations, but is not limited to just
/// these cases:
///
/// * The current process does not have the permission to access `path`.
///
/// # Example
/// ```rust,ignore
/// extern crate fs_extra;
/// use fs_extra::file::remove;
///
/// remove("foo.txt" )?; // Remove foo.txt
///
/// ```
pub fn remove<P>(path: P) -> Result<()>
where
P: AsRef<Path>,
{
if path.as_ref().exists() {
Ok(remove_file(path)?)
} else {
Ok(())
}
}
/// Read file contents, placing them into `String`.
///
/// # Errors
///
/// This function will return an error in the following situations, but is not limited to just
/// these cases:
///
/// * This `path` is not a file.
/// * This `path` file does not exist.
/// * The current process does not have the permission to access `path`.
///
/// # Example
/// ```rust,ignore
/// extern crate fs_extra;
/// use fs_extra::file::read_to_string;
///
/// let file_content = read_to_string("foo.txt" )?; // Get file content from foo.txt
/// println!("{}", file_content);
///
/// ```
pub fn read_to_string<P>(path: P) -> Result<String>
where
P: AsRef<Path>,
{
let path = path.as_ref();
if path.exists() && !path.is_file() {
if let Some(msg) = path.to_str() {
let msg = format!("Path \"{}\" is not a file!", msg);
err!(&msg, ErrorKind::InvalidFile);
}
err!("Path is not a file!", ErrorKind::InvalidFile);
}
let mut file = File::open(path)?;
let mut result = String::new();
file.read_to_string(&mut result)?;
Ok(result)
}
/// Write `String` content into file.
///
/// # Errors
///
/// This function will return an error in the following situations, but is not limited to just
/// these cases:
///
/// * This `path` is not a file.
/// * This `path` file does not exist.
/// * The current process does not have the permission to access `path`.
///
/// # Example
/// ```rust,ignore
/// extern crate fs_extra;
/// use fs_extra::file::read_to_string;
///
/// write_all("foo.txt", "contents" )?; // Create file foo.txt and send content inside
///
/// ```
pub fn write_all<P>(path: P, content: &str) -> Result<()>
where
P: AsRef<Path>,
{
let path = path.as_ref();
if path.exists() && !path.is_file() {
if let Some(msg) = path.to_str() {
let msg = format!("Path \"{}\" is not a file!", msg);
err!(&msg, ErrorKind::InvalidFile);
}
err!("Path is not a file!", ErrorKind::InvalidFile);
}
let mut f = File::create(path)?;
Ok(f.write_all(content.as_bytes())?)
}

802
vendor/fs_extra/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,802 @@
macro_rules! err {
($text:expr, $kind:expr) => {
return Err(Error::new($kind, $text))
};
($text:expr) => {
err!($text, ErrorKind::Other)
};
}
/// The error type for fs_extra operations on files and directories.
pub mod error;
/// This module includes additional methods for working with files.
///
/// One of the distinguishing features is receipt information
/// about process work with files.
///
/// # Example
/// ```rust,ignore
/// use std::path::Path;
/// use std::{thread, time};
/// use std::sync::mpsc::{self, TryRecvError};
///
/// extern crate fs_extra;
/// use fs_extra::file::*;
/// use fs_extra::error::*;
///
/// fn example_copy() -> Result<()> {
/// let path_from = Path::new("./temp");
/// let path_to = path_from.join("out");
/// let test_file = (path_from.join("test_file.txt"), path_to.join("test_file.txt"));
///
///
/// fs_extra::dir::create_all(&path_from, true)?;
/// fs_extra::dir::create_all(&path_to, true)?;
///
/// write_all(&test_file.0, "test_data")?;
/// assert!(test_file.0.exists());
/// assert!(!test_file.1.exists());
///
///
/// let options = CopyOptions {
/// buffer_size: 1,
/// ..Default::default()
/// }
/// let (tx, rx) = mpsc::channel();
/// thread::spawn(move || {
/// let handler = |process_info: TransitProcess| {
/// tx.send(process_info).unwrap();
/// thread::sleep(time::Duration::from_millis(500));
/// };
/// copy_with_progress(&test_file.0, &test_file.1, &options, handler).unwrap();
/// assert!(test_file.0.exists());
/// assert!(test_file.1.exists());
///
/// });
/// loop {
/// match rx.try_recv() {
/// Ok(process_info) => {
/// println!("{} of {} bytes",
/// process_info.copied_bytes,
/// process_info.total_bytes);
/// }
/// Err(TryRecvError::Disconnected) => {
/// println!("finished");
/// break;
/// }
/// Err(TryRecvError::Empty) => {}
/// }
/// }
/// Ok(())
///
/// }
///
///
/// fn main() {
/// example_copy();
/// }
///
/// ```
pub mod file;
/// This module includes additional methods for working with directories.
///
/// One of the additional features is information
/// about process and recursion operations.
///
/// # Example
/// ```rust,ignore
/// use std::path::Path;
/// use std::{thread, time};
/// use std::sync::mpsc::{self, TryRecvError};
///
/// extern crate fs_extra;
/// use fs_extra::dir::*;
/// use fs_extra::error::*;
///
/// fn example_copy() -> Result<()> {
///
/// let path_from = Path::new("./temp");
/// let path_to = path_from.join("out");
/// let test_folder = path_from.join("test_folder");
/// let dir = test_folder.join("dir");
/// let sub = dir.join("sub");
/// let file1 = dir.join("file1.txt");
/// let file2 = sub.join("file2.txt");
///
/// create_all(&sub, true)?;
/// create_all(&path_to, true)?;
/// fs_extra::file::write_all(&file1, "content1")?;
/// fs_extra::file::write_all(&file2, "content2")?;
///
/// assert!(dir.exists());
/// assert!(sub.exists());
/// assert!(file1.exists());
/// assert!(file2.exists());
///
///
/// let options = CopyOptions {
/// buffer_size: 1,
/// ..Default::default(),
/// };
/// let (tx, rx) = mpsc::channel();
/// thread::spawn(move || {
/// let handler = |process_info: TransitProcess| {
/// tx.send(process_info).unwrap();
/// thread::sleep(time::Duration::from_millis(500));
/// };
/// copy_with_progress(&test_folder, &path_to, &options, handler).unwrap();
/// });
///
/// loop {
/// match rx.try_recv() {
/// Ok(process_info) => {
/// println!("{} of {} bytes",
/// process_info.copied_bytes,
/// process_info.total_bytes);
/// }
/// Err(TryRecvError::Disconnected) => {
/// println!("finished");
/// break;
/// }
/// Err(TryRecvError::Empty) => {}
/// }
/// }
/// Ok(())
///
/// }
/// fn main() {
/// example_copy();
/// }
/// ```
///
pub mod dir;
use crate::error::*;
use std::path::Path;
/// Copies a list of directories and files to another place recursively. This function will
/// also copy the permission bits of the original files to destination files (not for
/// directories).
///
/// # Errors
///
/// This function will return an error in the following situations, but is not limited to just
/// these case:
///
/// * List `from` contains file or directory does not exist.
///
/// * List `from` contains file or directory with invalid name.
///
/// * The current process does not have the permission to access to file from `lists from` or
/// `to`.
///
/// # Example
///
/// ```rust,ignore
/// extern crate fs_extra;
/// use fs_extra::dir::copy;
///
/// let options = dir::CopyOptions::new(); //Initialize default values for CopyOptions
///
/// // copy dir1 and file1.txt to target/dir1 and target/file1.txt
/// let mut from_paths = Vec::new();
/// from_paths.push("source/dir1");
/// from_paths.push("source/file.txt");
/// copy_items(&from_paths, "target", &options)?;
/// ```
///
pub fn copy_items<P, Q>(from: &[P], to: Q, options: &dir::CopyOptions) -> Result<u64>
where
P: AsRef<Path>,
Q: AsRef<Path>,
{
let mut result: u64 = 0;
if options.content_only {
err!(
"Options 'content_only' not acccess for copy_items function",
ErrorKind::Other
);
}
for item in from {
let item = item.as_ref();
if item.is_dir() {
result += dir::copy(item, &to, options)?;
} else if let Some(file_name) = item.file_name() {
if let Some(file_name) = file_name.to_str() {
let file_options = file::CopyOptions {
overwrite: options.overwrite,
skip_exist: options.skip_exist,
..Default::default()
};
result += file::copy(item, to.as_ref().join(file_name), &file_options)?;
}
} else {
err!("Invalid file name", ErrorKind::InvalidFileName);
}
}
Ok(result)
}
/// A structure which includes information about the current status of copying or moving a directory.
pub struct TransitProcess {
/// Already copied bytes
pub copied_bytes: u64,
/// All the bytes which should be copied or moved (dir size).
pub total_bytes: u64,
/// Copied bytes on this time for file.
pub file_bytes_copied: u64,
/// Size of currently copied file.
pub file_total_bytes: u64,
/// Name of currently copied file.
pub file_name: String,
/// Name of currently copied folder.
pub dir_name: String,
/// Transit state
pub state: dir::TransitState,
}
impl Clone for TransitProcess {
fn clone(&self) -> TransitProcess {
TransitProcess {
copied_bytes: self.copied_bytes,
total_bytes: self.total_bytes,
file_bytes_copied: self.file_bytes_copied,
file_total_bytes: self.file_total_bytes,
file_name: self.file_name.clone(),
dir_name: self.dir_name.clone(),
state: self.state.clone(),
}
}
}
/// Copies a list of directories and files to another place recursively, with
/// information about progress. This function will also copy the permission bits of the
/// original files to destination files (not for directories).
///
/// # Errors
///
/// This function will return an error in the following situations, but is not limited to just
/// these case:
///
/// * List `from` contains file or directory does not exist.
///
/// * List `from` contains file or directory with invalid name.
///
/// * The current process does not have the permission to access to file from `lists from` or
/// `to`.
///
/// # Example
/// ```rust,ignore
///
/// extern crate fs_extra;
/// use fs_extra::dir::copy;
///
/// let options = dir::CopyOptions::new(); //Initialize default values for CopyOptions
/// let handle = |process_info: TransitProcess| {
/// println!("{}", process_info.total_bytes);
/// fs_extra::dir::TransitProcessResult::ContinueOrAbort
/// }
/// // copy dir1 and file1.txt to target/dir1 and target/file1.txt
/// let mut from_paths = Vec::new();
/// from_paths.push("source/dir1");
/// from_paths.push("source/file.txt");
/// copy_items_with_progress(&from_paths, "target", &options, handle)?;
/// ```
///
pub fn copy_items_with_progress<P, Q, F>(
from: &[P],
to: Q,
options: &dir::CopyOptions,
mut progress_handler: F,
) -> Result<u64>
where
P: AsRef<Path>,
Q: AsRef<Path>,
F: FnMut(TransitProcess) -> dir::TransitProcessResult,
{
if options.content_only {
err!(
"Options 'content_only' not access for copy_items_with_progress function",
ErrorKind::Other
);
}
let mut total_size = 0;
let mut list_paths = Vec::new();
for item in from {
let item = item.as_ref();
total_size += dir::get_size(item)?;
list_paths.push(item);
}
let mut result: u64 = 0;
let mut info_process = TransitProcess {
copied_bytes: 0,
total_bytes: total_size,
file_bytes_copied: 0,
file_total_bytes: 0,
file_name: String::new(),
dir_name: String::new(),
state: dir::TransitState::Normal,
};
let mut options = options.clone();
for item in list_paths {
if item.is_dir() {
if let Some(dir_name) = item.components().last() {
if let Ok(dir_name) = dir_name.as_os_str().to_os_string().into_string() {
info_process.dir_name = dir_name;
} else {
err!("Invalid folder from", ErrorKind::InvalidFolder);
}
} else {
err!("Invalid folder from", ErrorKind::InvalidFolder);
}
let copied_bytes = result;
let dir_options = options.clone();
let handler = |info: dir::TransitProcess| {
info_process.copied_bytes = copied_bytes + info.copied_bytes;
info_process.state = info.state;
let result = progress_handler(info_process.clone());
match result {
dir::TransitProcessResult::OverwriteAll => options.overwrite = true,
dir::TransitProcessResult::SkipAll => options.skip_exist = true,
_ => {}
}
result
};
result += dir::copy_with_progress(item, &to, &dir_options, handler)?;
} else {
let mut file_options = file::CopyOptions {
overwrite: options.overwrite,
skip_exist: options.skip_exist,
buffer_size: options.buffer_size,
};
if let Some(file_name) = item.file_name() {
if let Some(file_name) = file_name.to_str() {
info_process.file_name = file_name.to_string();
} else {
err!("Invalid file name", ErrorKind::InvalidFileName);
}
} else {
err!("Invalid file name", ErrorKind::InvalidFileName);
}
info_process.file_bytes_copied = 0;
info_process.file_total_bytes = item.metadata()?.len();
let copied_bytes = result;
let file_name = to.as_ref().join(info_process.file_name.clone());
let mut work = true;
let mut result_copy: Result<u64>;
while work {
{
let handler = |info: file::TransitProcess| {
info_process.copied_bytes = copied_bytes + info.copied_bytes;
info_process.file_bytes_copied = info.copied_bytes;
progress_handler(info_process.clone());
};
result_copy =
file::copy_with_progress(item, &file_name, &file_options, handler);
}
match result_copy {
Ok(val) => {
result += val;
work = false;
}
Err(err) => match err.kind {
ErrorKind::AlreadyExists => {
let mut info_process = info_process.clone();
info_process.state = dir::TransitState::Exists;
let user_decide = progress_handler(info_process);
match user_decide {
dir::TransitProcessResult::Overwrite => {
file_options.overwrite = true;
}
dir::TransitProcessResult::OverwriteAll => {
file_options.overwrite = true;
options.overwrite = true;
}
dir::TransitProcessResult::Skip => {
file_options.skip_exist = true;
}
dir::TransitProcessResult::SkipAll => {
file_options.skip_exist = true;
options.skip_exist = true;
}
dir::TransitProcessResult::Retry => {}
dir::TransitProcessResult::ContinueOrAbort => {
let err_msg = err.to_string();
err!(err_msg.as_str(), err.kind)
}
dir::TransitProcessResult::Abort => {
let err_msg = err.to_string();
err!(err_msg.as_str(), err.kind)
}
}
}
ErrorKind::PermissionDenied => {
let mut info_process = info_process.clone();
info_process.state = dir::TransitState::Exists;
let user_decide = progress_handler(info_process);
match user_decide {
dir::TransitProcessResult::Overwrite => {
err!("Overwrite denied for this situation!", ErrorKind::Other);
}
dir::TransitProcessResult::OverwriteAll => {
err!("Overwrite denied for this situation!", ErrorKind::Other);
}
dir::TransitProcessResult::Skip => {
file_options.skip_exist = true;
}
dir::TransitProcessResult::SkipAll => {
file_options.skip_exist = true;
options.skip_exist = true;
}
dir::TransitProcessResult::Retry => {}
dir::TransitProcessResult::ContinueOrAbort => {
let err_msg = err.to_string();
err!(err_msg.as_str(), err.kind)
}
dir::TransitProcessResult::Abort => {
let err_msg = err.to_string();
err!(err_msg.as_str(), err.kind)
}
}
}
_ => {
let err_msg = err.to_string();
err!(err_msg.as_str(), err.kind)
}
},
}
}
}
}
Ok(result)
}
/// Moves a list of directories and files to another place recursively. This function will
/// also copy the permission bits of the original files to destination files (not for
/// directories).
///
/// # Errors
///
/// This function will return an error in the following situations, but is not limited to just
/// these case:
///
/// * List `from` contains file or directory does not exist.
///
/// * List `from` contains file or directory with invalid name.
///
/// * The current process does not have the permission to access to file from `lists from` or
/// `to`.
///
/// # Example
///
/// ```rust,ignore
/// extern crate fs_extra;
/// use fs_extra::dir::copy;
///
/// let options = dir::CopyOptions::new(); //Initialize default values for CopyOptions
///
/// // move dir1 and file1.txt to target/dir1 and target/file1.txt
/// let mut from_paths = Vec::new();
/// from_paths.push("source/dir1");
/// from_paths.push("source/file.txt");
/// move_items(&from_paths, "target", &options)?;
/// ```
///
pub fn move_items<P, Q>(from_items: &[P], to: Q, options: &dir::CopyOptions) -> Result<u64>
where
P: AsRef<Path>,
Q: AsRef<Path>,
{
if options.content_only {
err!(
"Options 'content_only' not access for move_items function",
ErrorKind::Other
);
}
let mut total_size = 0;
let mut list_paths = Vec::new();
for item in from_items {
let item = item.as_ref();
total_size += dir::get_size(item)?;
list_paths.push(item);
}
let mut result = 0;
let mut info_process = TransitProcess {
copied_bytes: 0,
total_bytes: total_size,
file_bytes_copied: 0,
file_total_bytes: 0,
file_name: String::new(),
dir_name: String::new(),
state: dir::TransitState::Normal,
};
for item in list_paths {
if item.is_dir() {
if let Some(dir_name) = item.components().last() {
if let Ok(dir_name) = dir_name.as_os_str().to_os_string().into_string() {
info_process.dir_name = dir_name;
} else {
err!("Invalid folder from", ErrorKind::InvalidFolder);
}
} else {
err!("Invalid folder from", ErrorKind::InvalidFolder);
}
result += dir::move_dir(item, &to, options)?;
} else {
let file_options = file::CopyOptions {
overwrite: options.overwrite,
skip_exist: options.skip_exist,
buffer_size: options.buffer_size,
};
if let Some(file_name) = item.file_name() {
if let Some(file_name) = file_name.to_str() {
info_process.file_name = file_name.to_string();
} else {
err!("Invalid file name", ErrorKind::InvalidFileName);
}
} else {
err!("Invalid file name", ErrorKind::InvalidFileName);
}
info_process.file_bytes_copied = 0;
info_process.file_total_bytes = item.metadata()?.len();
let file_name = to.as_ref().join(info_process.file_name.clone());
result += file::move_file(item, &file_name, &file_options)?;
}
}
Ok(result)
}
/// Moves a list of directories and files to another place recursively, with
/// information about progress. This function will also copy the permission bits of the
/// original files to destination files (not for directories).
///
/// # Errors
///
/// This function will return an error in the following situations, but is not limited to just
/// these case:
///
/// * List `from` contains file or directory does not exist.
///
/// * List `from` contains file or directory with invalid name.
///
/// * The current process does not have the permission to access to file from `lists from` or
/// `to`.
///
/// # Example
///
/// ```rust,ignore
/// extern crate fs_extra;
/// use fs_extra::dir::copy;
///
/// let options = dir::CopyOptions::new(); //Initialize default values for CopyOptions
/// let handle = |process_info: TransitProcess| {
/// println!("{}", process_info.total_bytes);
/// fs_extra::dir::TransitProcessResult::ContinueOrAbort
/// }
/// // move dir1 and file1.txt to target/dir1 and target/file1.txt
/// let mut from_paths = Vec::new();
/// from_paths.push("source/dir1");
/// from_paths.push("source/file.txt");
/// move_items_with_progress(&from_paths, "target", &options, handle)?;
/// ```
///
pub fn move_items_with_progress<P, Q, F>(
from_items: &[P],
to: Q,
options: &dir::CopyOptions,
mut progress_handler: F,
) -> Result<u64>
where
P: AsRef<Path>,
Q: AsRef<Path>,
F: FnMut(TransitProcess) -> dir::TransitProcessResult,
{
if options.content_only {
err!(
"Options 'content_only' not access for move_items_with_progress function",
ErrorKind::Other
);
}
let mut total_size = 0;
let mut list_paths = Vec::new();
for item in from_items {
let item = item.as_ref();
total_size += dir::get_size(item)?;
list_paths.push(item);
}
let mut result = 0;
let mut info_process = TransitProcess {
copied_bytes: 0,
total_bytes: total_size,
file_bytes_copied: 0,
file_total_bytes: 0,
file_name: String::new(),
dir_name: String::new(),
state: dir::TransitState::Normal,
};
let mut options = options.clone();
for item in list_paths {
if item.is_dir() {
if let Some(dir_name) = item.components().last() {
if let Ok(dir_name) = dir_name.as_os_str().to_os_string().into_string() {
info_process.dir_name = dir_name;
} else {
err!("Invalid folder from", ErrorKind::InvalidFolder);
}
} else {
err!("Invalid folder from", ErrorKind::InvalidFolder);
}
let copied_bytes = result;
let dir_options = options.clone();
let handler = |info: dir::TransitProcess| {
info_process.copied_bytes = copied_bytes + info.copied_bytes;
info_process.state = info.state;
let result = progress_handler(info_process.clone());
match result {
dir::TransitProcessResult::OverwriteAll => options.overwrite = true,
dir::TransitProcessResult::SkipAll => options.skip_exist = true,
_ => {}
}
result
};
result += dir::move_dir_with_progress(item, &to, &dir_options, handler)?;
} else {
let mut file_options = file::CopyOptions {
overwrite: options.overwrite,
skip_exist: options.skip_exist,
buffer_size: options.buffer_size,
};
if let Some(file_name) = item.file_name() {
if let Some(file_name) = file_name.to_str() {
info_process.file_name = file_name.to_string();
} else {
err!("Invalid file name", ErrorKind::InvalidFileName);
}
} else {
err!("Invalid file name", ErrorKind::InvalidFileName);
}
info_process.file_bytes_copied = 0;
info_process.file_total_bytes = item.metadata()?.len();
let copied_bytes = result;
let file_name = to.as_ref().join(info_process.file_name.clone());
let mut work = true;
let mut result_copy: Result<u64>;
while work {
{
let handler = |info: file::TransitProcess| {
info_process.copied_bytes = copied_bytes + info.copied_bytes;
info_process.file_bytes_copied = info.copied_bytes;
progress_handler(info_process.clone());
};
result_copy =
file::move_file_with_progress(item, &file_name, &file_options, handler);
}
match result_copy {
Ok(val) => {
result += val;
work = false;
}
Err(err) => match err.kind {
ErrorKind::AlreadyExists => {
let mut info_process = info_process.clone();
info_process.state = dir::TransitState::Exists;
let user_decide = progress_handler(info_process);
match user_decide {
dir::TransitProcessResult::Overwrite => {
file_options.overwrite = true;
}
dir::TransitProcessResult::OverwriteAll => {
file_options.overwrite = true;
options.overwrite = true;
}
dir::TransitProcessResult::Skip => {
file_options.skip_exist = true;
}
dir::TransitProcessResult::SkipAll => {
file_options.skip_exist = true;
options.skip_exist = true;
}
dir::TransitProcessResult::Retry => {}
dir::TransitProcessResult::ContinueOrAbort => {
let err_msg = err.to_string();
err!(err_msg.as_str(), err.kind)
}
dir::TransitProcessResult::Abort => {
let err_msg = err.to_string();
err!(err_msg.as_str(), err.kind)
}
}
}
ErrorKind::PermissionDenied => {
let mut info_process = info_process.clone();
info_process.state = dir::TransitState::Exists;
let user_decide = progress_handler(info_process);
match user_decide {
dir::TransitProcessResult::Overwrite => {
err!("Overwrite denied for this situation!", ErrorKind::Other);
}
dir::TransitProcessResult::OverwriteAll => {
err!("Overwrite denied for this situation!", ErrorKind::Other);
}
dir::TransitProcessResult::Skip => {
file_options.skip_exist = true;
}
dir::TransitProcessResult::SkipAll => {
file_options.skip_exist = true;
options.skip_exist = true;
}
dir::TransitProcessResult::Retry => {}
dir::TransitProcessResult::ContinueOrAbort => {
let err_msg = err.to_string();
err!(err_msg.as_str(), err.kind)
}
dir::TransitProcessResult::Abort => {
let err_msg = err.to_string();
err!(err_msg.as_str(), err.kind)
}
}
}
_ => {
let err_msg = err.to_string();
err!(err_msg.as_str(), err.kind)
}
},
}
}
}
}
Ok(result)
}
/// Removes a list of files or directories.
///
/// # Example
///
/// ```rust,ignore
/// let mut from_paths = Vec::new();
/// from_paths.push("source/dir1");
/// from_paths.push("source/file.txt");
///
/// remove_items(&from_paths).unwrap();
/// ```
///
pub fn remove_items<P>(from_items: &[P]) -> Result<()>
where
P: AsRef<Path>,
{
for item in from_items {
let item = item.as_ref();
if item.is_dir() {
dir::remove(item)?;
} else {
file::remove(item)?
}
}
Ok(())
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
{"name":"fs_extra","vers":"1.3.0","deps":[],"features":{},"features2":null,"cksum":"70e526d8b11cd859aaa72b49f9db5e01115514f45a550eb8ca976278086093ef","yanked":null,"links":null,"rust_version":null,"v":2}

4824
vendor/fs_extra/tests/dir.rs vendored Normal file

File diff suppressed because it is too large Load Diff

1036
vendor/fs_extra/tests/file.rs vendored Normal file

File diff suppressed because it is too large Load Diff

3883
vendor/fs_extra/tests/lib.rs vendored Normal file

File diff suppressed because it is too large Load Diff