fs_extra-1.2.0/.cargo_vcs_info.json0000644000000001121372114405600127420ustar00{ "git": { "sha1": "9b972027bac127236d00da3f807891d1972ff49c" } } fs_extra-1.2.0/Cargo.toml0000644000000021051372114405600107440ustar00# 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] name = "fs_extra" version = "1.2.0" authors = ["Denis Kurilenko "] include = ["**/*.rs", "Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md"] description = "Expanding opportunities standard library std::fs and std::io. Recursively copy folders with recept 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] fs_extra-1.2.0/Cargo.toml.orig010064400017500001731000000011201372114222300144230ustar0000000000000000[package] name = "fs_extra" version = "1.2.0" description = "Expanding opportunities standard library std::fs and std::io. Recursively copy folders with recept information about process and much more." license = "MIT" authors = ["Denis Kurilenko "] keywords = ["filesystem", "recursion", "copy", "dir", "file"] homepage = "https://github.com/webdesus/fs_extra" documentation = "https://docs.rs/fs_extra" repository = "https://github.com/webdesus/fs_extra" include = [ "**/*.rs", "Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md", ] [dependencies] fs_extra-1.2.0/LICENSE010064400017500001731000000020601360570752700125640ustar0000000000000000MIT 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. fs_extra-1.2.0/README.md010064400017500001731000000156041372114214200130270ustar0000000000000000# 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.2.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(); } ``` fs_extra-1.2.0/src/dir.rs010064400017500001731000001255201372114334700134720ustar0000000000000000use error::*; use std::collections::{HashMap, HashSet}; use std::fs::{create_dir, create_dir_all, read_dir, remove_dir_all, Metadata}; use std::path::{Path, PathBuf}; use std::time::SystemTime; /// Options and flags which can be used to configure how a file will be copied or moved. #[derive(Clone)] pub struct CopyOptions { /// Sets the option true for overwrite existing files. pub overwrite: bool, /// Sets the option true for skipe existing files. pub skip_exist: bool, /// Sets buffer size for copy/move work only with receipt information about process work. pub buffer_size: usize, /// Sets the option true for recursively copying a directory with a new name or place it inside the destination.(same behaviors like cp -r in Unix) pub copy_inside: bool, /// Sets the option true, for copy only content without a created folder in the destination folder pub content_only: bool, /// Sets levels reading. Set 0 for read all directory folder. By default 0. /// /// Warrning: Work only for copy operations! pub depth: u64, } impl CopyOptions { /// Initialize struct CopyOptions with default value. /// /// ```rust,ignore /// overwrite: false /// /// skip_exist: false /// /// buffer_size: 64000 //64kb /// /// copy_inside: false /// ``` pub fn new() -> CopyOptions { CopyOptions { overwrite: false, skip_exist: false, buffer_size: 64000, //64kb copy_inside: false, content_only: false, depth: 0, } } } impl Default for CopyOptions { fn default() -> Self { CopyOptions::new() } } /// Options and flags which can be used to configure how read a directory. #[derive(Clone, Default)] pub struct DirOptions { /// Sets levels reading. Set value 0 for read all directory folder. By default 0. pub depth: u64, } impl DirOptions { /// Initialize struct DirOptions with default value. pub fn new() -> DirOptions { Default::default() } } /// A structure which imclude information about directory pub struct DirContent { /// Directory size. pub dir_size: u64, /// List all files directory and sub directories. pub files: Vec, /// List all folders and sub folders directory. pub directories: Vec, } /// A structure which include information about the current status of the copy or move directory. pub struct TransitProcess { /// Copied bytes on this time for folder pub copied_bytes: u64, /// All the bytes which should to copy or move (dir size). pub total_bytes: u64, /// Copied bytes on this time for file. pub file_bytes_copied: u64, /// Size current copied file. pub file_total_bytes: u64, /// Name current copied file. pub file_name: String, /// Transit state pub state: TransitState, } /// #[derive(Hash, Eq, PartialEq, Clone)] pub enum TransitState { /// Standart state. Normal, /// Pause state when destination path is exist. Exists, /// Pause state when current process does not have the permission rights to acess from or to /// path. NoAccess, } /// Available returns codes for user decide pub enum TransitProcessResult { /// Rewrite exist file or directory. Overwrite, /// Rewrite for all exist files or directories. OverwriteAll, /// Skip current problem file or directory. Skip, /// Skip for all problems file or directory. SkipAll, /// Retry current operation. Retry, /// Abort current operation. Abort, /// Continue execute process if process not have error and abort if process content error. ContinueOrAbort, } 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(), state: self.state.clone(), } } } /// Available attributes for get information about directory entry. #[derive(Hash, Eq, PartialEq, Clone)] pub enum DirEntryAttr { /// Folder name or file name without extension. Name, /// File extension. Ext, /// Folder name or file name with extention. FullName, /// Path to file or directory. Path, /// Dos path to file or directory. DosPath, /// File size in bytes. FileSize, /// Size file or directory in bytes. /// /// `Attention!`: This operation very expensive and sometimes required additional rights. Size, /// Return whether entry is directory or not. IsDir, /// Return whether entry is file or not. IsFile, /// Last modification time for directory entry. Modified, /// Last access time for directory entry. Accessed, /// Created time for directory entry. /// /// `Attention!`: Not supported UNIX platform. Created, /// Return or not return base information target folder. BaseInfo, } /// Available types for directory entry. pub enum DirEntryValue { /// String type String(String), /// Boolean type Boolean(bool), /// SystemTime type SystemTime(SystemTime), /// u64 type U64(u64), } /// Result returned by the `ls` function. pub struct LsResult { /// Base folder target path pub base: HashMap, /// Collection directory entry with information. pub items: Vec>, } /// Returned information about directory entry with information which you choose in config. /// /// This function takes to arguments: /// /// * `path` - Path to directory. /// /// * `config` - Set attributes which you want see inside return data. /// /// # Errors /// /// This function will return an error in the following situations, but is not limited to just /// these cases: /// /// * This `path` does not exist. /// * Invalid `path`. /// * The current process does not have the permission rights to access `path`. /// /// #Examples /// /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::{get_details_entry, DirEntryAttr}; /// use std::collections::{HashMap, HashSet}; /// /// let mut config = HashSet::new(); /// config.insert(DirEntryAttr::Name); /// config.insert(DirEntryAttr::Size); /// /// let entry_info = get_details_entry("test", &config); /// assert_eq!(2, entry_info.len()); /// ``` pub fn get_details_entry

( path: P, config: &HashSet, ) -> Result> where P: AsRef, { let path = path.as_ref(); let metadata = path.metadata()?; get_details_entry_with_meta(path, config, metadata) } fn get_details_entry_with_meta

( path: P, config: &HashSet, metadata: Metadata, ) -> Result> where P: AsRef, { let path = path.as_ref(); let mut item = HashMap::new(); if config.contains(&DirEntryAttr::Name) { if metadata.is_dir() { if let Some(file_name) = path.file_name() { item.insert( DirEntryAttr::Name, DirEntryValue::String(file_name.to_os_string().into_string()?), ); } else { item.insert(DirEntryAttr::Name, DirEntryValue::String(String::new())); } } else { if let Some(file_stem) = path.file_stem() { item.insert( DirEntryAttr::Name, DirEntryValue::String(file_stem.to_os_string().into_string()?), ); } else { item.insert(DirEntryAttr::Name, DirEntryValue::String(String::new())); } } } if config.contains(&DirEntryAttr::Ext) { if let Some(value) = path.extension() { item.insert( DirEntryAttr::Ext, DirEntryValue::String(value.to_os_string().into_string()?), ); } else { item.insert(DirEntryAttr::Ext, DirEntryValue::String(String::from(""))); } } if config.contains(&DirEntryAttr::FullName) { if let Some(file_name) = path.file_name() { item.insert( DirEntryAttr::FullName, DirEntryValue::String(file_name.to_os_string().into_string()?), ); } else { item.insert(DirEntryAttr::FullName, DirEntryValue::String(String::new())); } } if config.contains(&DirEntryAttr::Path) { let mut result_path: PathBuf; match path.canonicalize() { Ok(new_path) => { result_path = new_path; } Err(_) => { if let Some(parent_path) = path.parent() { if let Some(name) = path.file_name() { result_path = parent_path.canonicalize()?; result_path.push(name); } else { err!("Error get part name path", ErrorKind::Other); } } else { err!("Error get parent path", ErrorKind::Other); } } } let mut path = result_path.as_os_str().to_os_string().into_string()?; if path.find("\\\\?\\") == Some(0) { path = path[4..].to_string(); } item.insert(DirEntryAttr::Path, DirEntryValue::String(path)); } if config.contains(&DirEntryAttr::DosPath) { let mut result_path: PathBuf; match path.canonicalize() { Ok(new_path) => { result_path = new_path; } Err(_) => { if let Some(parent_path) = path.parent() { if let Some(name) = path.file_name() { result_path = parent_path.canonicalize()?; result_path.push(name); } else { err!("Error get part name path", ErrorKind::Other); } } else { err!("Error get parent path", ErrorKind::Other); } } } let path = result_path.as_os_str().to_os_string().into_string()?; item.insert(DirEntryAttr::DosPath, DirEntryValue::String(path)); } if config.contains(&DirEntryAttr::Size) { item.insert(DirEntryAttr::Size, DirEntryValue::U64(get_size(&path)?)); } if config.contains(&DirEntryAttr::FileSize) { item.insert(DirEntryAttr::FileSize, DirEntryValue::U64(metadata.len())); } if config.contains(&DirEntryAttr::IsDir) { item.insert( DirEntryAttr::IsDir, DirEntryValue::Boolean(metadata.is_dir()), ); } if config.contains(&DirEntryAttr::IsFile) { item.insert( DirEntryAttr::IsFile, DirEntryValue::Boolean(metadata.is_file()), ); } if config.contains(&DirEntryAttr::Modified) { item.insert( DirEntryAttr::Modified, DirEntryValue::SystemTime(metadata.modified()?), ); } if config.contains(&DirEntryAttr::Accessed) { item.insert( DirEntryAttr::Accessed, DirEntryValue::SystemTime(metadata.accessed()?), ); } if config.contains(&DirEntryAttr::Created) { item.insert( DirEntryAttr::Created, DirEntryValue::SystemTime(metadata.created()?), ); } Ok(item) } /// Returned collection directory entries with information which you choose in config. /// /// This function takes to arguments: /// /// * `path` - Path to directory. /// /// * `config` - Set attributes which you want see inside return data. /// /// # Errors /// /// This function will return an error in the following situations, but is not limited to just /// these cases: /// /// * This `path` directory does not exist. /// * Invalid `path`. /// * The current process does not have the permission rights to access `path`. /// /// #Examples /// /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::{ls, DirEntryAttr, LsResult}; /// use std::collections::HashSet; /// /// let mut config = HashSet::new(); /// config.insert(DirEntryAttr::Name); /// config.insert(DirEntryAttr::Size); /// config.insert(DirEntryAttr::BaseInfo); /// /// let result = ls("test", &config); /// assert_eq!(2, ls_result.items.len()); /// assert_eq!(2, ls_result.base.len()); /// ``` pub fn ls

(path: P, config: &HashSet) -> Result where P: AsRef, { let mut items = Vec::new(); let path = path.as_ref(); if !path.is_dir() { err!("Path does not directory", ErrorKind::InvalidFolder); } for entry in read_dir(&path)? { let entry = entry?; let path = entry.path(); let metadata = entry.metadata()?; let item = get_details_entry_with_meta(path, &config, metadata)?; items.push(item); } let mut base = HashMap::new(); if config.contains(&DirEntryAttr::BaseInfo) { base = get_details_entry(&path, &config)?; } Ok(LsResult { items: items, base: base, }) } /// Creates a new, empty directory at the provided path. /// /// This function takes to arguments: /// /// * `path` - Path to new directory. /// /// * `erase` - If set true and folder exist, then folder will be erased. /// /// #Errors /// /// This function will return an error in the following situations, /// but is not limited to just these cases: /// /// * User lacks permissions to create directory at `path`. /// /// * `path` already exists if `erase` set false. /// /// #Examples /// /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::create; /// /// create("dir", false); // create directory /// ``` pub fn create

(path: P, erase: bool) -> Result<()> where P: AsRef, { if erase && path.as_ref().exists() { remove(&path)?; } Ok(create_dir(&path)?) } /// Recursively create a directory and all of its parent components if they are missing. /// /// This function takes to arguments: /// /// * `path` - Path to new directory. /// /// * `erase` - If set true and folder exist, then folder will be erased. /// ///#Errors /// /// This function will return an error in the following situations, /// but is not limited to just these cases: /// /// * User lacks permissions to create directory at `path`. /// /// * `path` already exists if `erase` set false. /// /// #Examples /// /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::create_all; /// /// create_all("/some/dir", false); // create directory some and dir pub fn create_all

(path: P, erase: bool) -> Result<()> where P: AsRef, { if erase && path.as_ref().exists() { remove(&path)?; } Ok(create_dir_all(&path)?) } /// Copies the directory contents from one place to another using recursive method. /// This function will also copy the permission bits of the original files to /// destionation files (not for directories). /// /// # 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 directory. /// * This `from` directory does not exist. /// * Invalid folder name for `from` or `to`. /// * The current process does not have the permission rights to access `from` or write `to`. /// /// # Example /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::copy; /// /// let options = CopyOptions::new(); //Initialize default values for CopyOptions /// // options.mirror_copy = true; // To mirror copy the whole structure of the source directory /// /// /// // copy source/dir1 to target/dir1 /// copy("source/dir1", "target/dir1", &options)?; /// /// ``` pub fn copy(from: P, to: Q, options: &CopyOptions) -> Result where P: AsRef, Q: AsRef, { 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_dir() { if let Some(msg) = from.to_str() { let msg = format!("Path \"{}\" is not a directory!", msg); err!(&msg, ErrorKind::InvalidFolder); } err!("Path is not a directory!", ErrorKind::InvalidFolder); } let dir_name; if let Some(val) = from.components().last() { dir_name = val.as_os_str(); } else { err!("Invalid folder from", ErrorKind::InvalidFolder); } let mut to: PathBuf = to.as_ref().to_path_buf(); if !options.content_only && ((options.copy_inside && to.exists()) || !options.copy_inside) { to.push(dir_name); } let mut read_options = DirOptions::new(); if options.depth > 0 { read_options.depth = options.depth; } let dir_content = get_dir_content2(from, &read_options)?; for directory in dir_content.directories { let tmp_to = Path::new(&directory).strip_prefix(from)?; let dir = to.join(&tmp_to); if !dir.exists() { if options.copy_inside { create_all(dir, false)?; } else { create(dir, false)?; } } } let mut result: u64 = 0; for file in dir_content.files { let to = to.to_path_buf(); let tp = Path::new(&file).strip_prefix(from)?; let path = to.join(&tp); let file_options = super::file::CopyOptions { overwrite: options.overwrite, skip_exist: options.skip_exist, buffer_size: options.buffer_size, }; let mut result_copy: Result; let mut work = true; while work { result_copy = super::file::copy(&file, &path, &file_options); match result_copy { Ok(val) => { result += val; work = false; } Err(err) => { let err_msg = err.to_string(); err!(err_msg.as_str(), err.kind) } } } } Ok(result) } /// Return DirContent which containt information about directory: /// /// * Size directory. /// * List all files source directory(files subdirectories included too). /// * List all directory and subdirectories source path. /// /// # Errors /// /// This function will return an error in the following situations, but is not limited to just /// these cases: /// /// * This `path` directory does not exist. /// * Invalid `path`. /// * The current process does not have the permission rights to access `path`. /// /// # Examples /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::get_dir_content; /// /// let dir_content = get_dir_content("dir")?; /// for directory in dir_content.directories { /// println!("{}", directory); // print directory path /// } /// ``` /// pub fn get_dir_content

(path: P) -> Result where P: AsRef, { let options = DirOptions::new(); get_dir_content2(path, &options) } /// Return DirContent which containt information about directory: /// /// * Size directory. /// * List all files source directory(files subdirectories included too). /// * List all directory and subdirectories source path. /// /// # Errors /// /// This function will return an error in the following situations, but is not limited to just /// these cases: /// /// * This `path` directory does not exist. /// * Invalid `path`. /// * The current process does not have the permission rights to access `path`. /// /// # Examples /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::get_dir_content2; /// /// let options = DirOptions::new(); /// options.depth = 3; // Get 3 levels of folder. /// let dir_content = get_dir_content2("dir", &options)?; /// for directory in dir_content.directories { /// println!("{}", directory); // print directory path /// } /// ``` /// pub fn get_dir_content2

(path: P, options: &DirOptions) -> Result where P: AsRef, { let mut depth = 0; if options.depth != 0 { depth = options.depth + 1; } _get_dir_content(path, depth) } fn _get_dir_content

(path: P, mut depth: u64) -> Result where P: AsRef, { let mut directories = Vec::new(); let mut files = Vec::new(); let mut dir_size = 0; let item = path.as_ref().to_str(); if !item.is_some() { err!("Invalid path", ErrorKind::InvalidPath); } let item = item.unwrap().to_string(); if path.as_ref().is_dir() { directories.push(item); if depth == 0 || depth > 1 { if depth > 1 { depth -= 1; } for entry in read_dir(&path)? { let _path = entry?.path(); match _get_dir_content(_path, depth) { Ok(items) => { let mut _files = items.files; let mut _dirrectories = items.directories; dir_size += items.dir_size; files.append(&mut _files); directories.append(&mut _dirrectories); } Err(err) => return Err(err), } } } } else { dir_size = path.as_ref().metadata()?.len(); files.push(item); } Ok(DirContent { dir_size: dir_size, files: files, directories: directories, }) } /// Returns the size of the file or directory /// /// # Errors /// /// This function will return an error in the following situations, but is not limited to just /// these cases: /// /// * This `path` directory does not exist. /// * Invalid `path`. /// * The current process does not have the permission rights to access `path`. /// /// # Examples /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::get_size; /// /// let folder_size = get_size("dir")?; /// println!("{}", folder_size); // print directory sile in bytes /// ``` pub fn get_size

(path: P) -> Result where P: AsRef, { let mut result = 0; if path.as_ref().is_dir() { for entry in read_dir(&path)? { let _path = entry?.path(); if _path.is_file() { result += _path.metadata()?.len(); } else { result += get_size(_path)?; } } } else { result = path.as_ref().metadata()?.len(); } Ok(result) } /// Copies the directory contents from one place to another using recursive method, /// with recept information about process. This function will also copy the /// permission bits of the original files to destionation files (not for directories). /// /// # 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 directory. /// * This `from` directory does not exist. /// * Invalid folder name for `from` or `to`. /// * The current process does not have the permission rights to access `from` or write `to`. /// /// # Example /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::copy; /// /// let options = CopyOptions::new(); //Initialize default values for CopyOptions /// let handle = |process_info: TransitProcess| { /// println!("{}", process_info.total_bytes); /// fs_extra::dir::TransitProcessResult::ContinueOrAbort /// } /// // copy source/dir1 to target/dir1 /// copy_with_progress("source/dir1", "target/dir1", &options, handle)?; /// /// ``` pub fn copy_with_progress( from: P, to: Q, options: &CopyOptions, mut progress_handler: F, ) -> Result where P: AsRef, Q: AsRef, F: FnMut(TransitProcess) -> TransitProcessResult, { 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 ); } let mut to: PathBuf = to.as_ref().to_path_buf(); if !from.is_dir() { if let Some(msg) = from.to_str() { let msg = format!("Path \"{}\" is not a directory!", msg); err!(&msg, ErrorKind::InvalidFolder); } err!("Path is not a directory!", ErrorKind::InvalidFolder); } let dir_name; if let Some(val) = from.components().last() { dir_name = val.as_os_str(); } else { err!("Invalid folder from", ErrorKind::InvalidFolder); } if !options.content_only && ((options.copy_inside && to.exists()) || !options.copy_inside) { to.push(dir_name); } let mut read_options = DirOptions::new(); if options.depth > 0 { read_options.depth = options.depth; } let dir_content = get_dir_content2(from, &read_options)?; for directory in dir_content.directories { let tmp_to = Path::new(&directory).strip_prefix(from)?; let dir = to.join(&tmp_to); if !dir.exists() { if options.copy_inside { create_all(dir, false)?; } else { create(dir, false)?; } } } let mut result: u64 = 0; let mut info_process = TransitProcess { copied_bytes: 0, total_bytes: dir_content.dir_size, file_bytes_copied: 0, file_total_bytes: 0, file_name: String::new(), state: TransitState::Normal, }; let mut options = options.clone(); for file in dir_content.files { let mut to = to.to_path_buf(); let tp = Path::new(&file).strip_prefix(from)?; let path = to.join(&tp); let file_name = path.file_name(); if !file_name.is_some() { err!("No file name"); } let file_name = file_name.unwrap(); to.push(file_name); let mut file_options = super::file::CopyOptions { overwrite: options.overwrite, skip_exist: options.skip_exist, buffer_size: options.buffer_size, }; if let Some(file_name) = file_name.to_str() { info_process.file_name = file_name.to_string(); } else { err!("Invalid file name", ErrorKind::InvalidFileName); } info_process.file_bytes_copied = 0; info_process.file_total_bytes = Path::new(&file).metadata()?.len(); let mut result_copy: Result; let mut work = true; let copied_bytes = result; while work { { let _progress_handler = |info: super::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 = super::file::copy_with_progress(&file, &path, &file_options, _progress_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 = TransitState::Exists; let user_decide = progress_handler(info_process); match user_decide { TransitProcessResult::Overwrite => { file_options.overwrite = true; } TransitProcessResult::OverwriteAll => { file_options.overwrite = true; options.overwrite = true; } TransitProcessResult::Skip => { file_options.skip_exist = true; } TransitProcessResult::SkipAll => { file_options.skip_exist = true; options.skip_exist = true; } TransitProcessResult::Retry => {} TransitProcessResult::ContinueOrAbort => { let err_msg = err.to_string(); err!(err_msg.as_str(), err.kind) } 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 = TransitState::Exists; let user_decide = progress_handler(info_process); match user_decide { TransitProcessResult::Overwrite => { err!("Overwrite denied for this situation!", ErrorKind::Other); } TransitProcessResult::OverwriteAll => { err!("Overwrite denied for this situation!", ErrorKind::Other); } TransitProcessResult::Skip => { file_options.skip_exist = true; } TransitProcessResult::SkipAll => { file_options.skip_exist = true; options.skip_exist = true; } TransitProcessResult::Retry => {} TransitProcessResult::ContinueOrAbort => { let err_msg = err.to_string(); err!(err_msg.as_str(), err.kind) } 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 the directory contents from one place to another. /// This function will also copy the permission bits of the original files to /// destionation files (not for directories). /// /// # 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 directory. /// * This `from` directory does not exist. /// * Invalid folder name for `from` or `to`. /// * The current process does not have the permission rights to access `from` or write `to`. /// /// # Example /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::move_dir; /// /// let options = CopyOptions::new(); //Initialize default values for CopyOptions /// /// // move source/dir1 to target/dir1 /// move_dir("source/dir1", "target/dir1", &options)?; /// /// ``` pub fn move_dir(from: P, to: Q, options: &CopyOptions) -> Result where P: AsRef, Q: AsRef, { let mut is_remove = true; if options.skip_exist && to.as_ref().exists() && !options.overwrite { is_remove = false; } let from = from.as_ref(); if !from.exists() { if let Some(msg) = from.to_str() { let msg = format!("Path \"{}\" does not exist", msg); err!(&msg, ErrorKind::NotFound); } err!( "Path does not exist or you don't have access!", ErrorKind::NotFound ); } let mut to: PathBuf = to.as_ref().to_path_buf(); if !from.is_dir() { if let Some(msg) = from.to_str() { let msg = format!( "Path \"{}\" is not a directory or you don't have access!", msg ); err!(&msg, ErrorKind::InvalidFolder); } err!( "Path is not a directory or you don't have access!", ErrorKind::InvalidFolder ); } let dir_name; if let Some(val) = from.components().last() { dir_name = val.as_os_str(); } else { err!("Invalid folder from", ErrorKind::InvalidFolder); } if !options.content_only && ((options.copy_inside && to.exists()) || !options.copy_inside) { to.push(dir_name); } let dir_content = get_dir_content(from)?; for directory in dir_content.directories { let tmp_to = Path::new(&directory).strip_prefix(from)?; let dir = to.join(&tmp_to); if !dir.exists() { if options.copy_inside { create_all(dir, false)?; } else { create(dir, false)?; } } } let mut result: u64 = 0; for file in dir_content.files { let to = to.to_path_buf(); let tp = Path::new(&file).strip_prefix(from)?; let path = to.join(&tp); let file_options = super::file::CopyOptions { overwrite: options.overwrite, skip_exist: options.skip_exist, buffer_size: options.buffer_size, }; let mut result_copy: Result; let mut work = true; while work { { result_copy = super::file::move_file(&file, &path, &file_options); match result_copy { Ok(val) => { result += val; work = false; } Err(err) => { let err_msg = err.to_string(); err!(err_msg.as_str(), err.kind) } } } } } if is_remove { remove(from)?; } Ok(result) } /// Moves the directory contents from one place to another with recept information about process. /// This function will also copy the permission bits of the original files to /// destionation files (not for directories). /// /// # 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 directory. /// * This `from` directory does not exist. /// * Invalid folder name for `from` or `to`. /// * The current process does not have the permission rights to access `from` or write `to`. /// /// # Example /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::move_dir_with_progress; /// /// let options = CopyOptions::new(); //Initialize default values for CopyOptions /// let handle = |process_info: TransitProcess| { /// println!("{}", process_info.total_bytes); /// fs_extra::dir::TransitProcessResult::ContinueOrAbort /// } /// /// // move source/dir1 to target/dir1 /// move_dir_with_progress("source/dir1", "target/dir1", &options, handle)?; /// /// ``` pub fn move_dir_with_progress( from: P, to: Q, options: &CopyOptions, mut progress_handler: F, ) -> Result where P: AsRef, Q: AsRef, F: FnMut(TransitProcess) -> TransitProcessResult, { let mut is_remove = true; if options.skip_exist && to.as_ref().exists() && !options.overwrite { is_remove = false; } 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 ); } let mut to: PathBuf = to.as_ref().to_path_buf(); if !from.is_dir() { if let Some(msg) = from.to_str() { let msg = format!("Path \"{}\" is not a directory!", msg); err!(&msg, ErrorKind::InvalidFolder); } err!("Path is not a directory!", ErrorKind::InvalidFolder); } let dir_name; if let Some(val) = from.components().last() { dir_name = val.as_os_str(); } else { err!("Invalid folder from", ErrorKind::InvalidFolder); } if !options.content_only && ((options.copy_inside && to.exists()) || !options.copy_inside) { to.push(dir_name); } let dir_content = get_dir_content(from)?; for directory in dir_content.directories { let tmp_to = Path::new(&directory).strip_prefix(from)?; let dir = to.join(&tmp_to); if !dir.exists() { if options.copy_inside { create_all(dir, false)?; } else { create(dir, false)?; } } } let mut result: u64 = 0; let mut info_process = TransitProcess { copied_bytes: 0, total_bytes: dir_content.dir_size, file_bytes_copied: 0, file_total_bytes: 0, file_name: String::new(), state: TransitState::Normal, }; let mut options = options.clone(); for file in dir_content.files { let mut to = to.to_path_buf(); let tp = Path::new(&file).strip_prefix(from)?; let path = to.join(&tp); let file_name = path.file_name(); if !file_name.is_some() { err!("No file name"); } let file_name = file_name.unwrap(); to.push(file_name); let mut file_options = super::file::CopyOptions { overwrite: options.overwrite, skip_exist: options.skip_exist, buffer_size: options.buffer_size, }; if let Some(file_name) = file_name.to_str() { info_process.file_name = file_name.to_string(); } else { err!("Invalid file name", ErrorKind::InvalidFileName); } info_process.file_bytes_copied = 0; info_process.file_total_bytes = Path::new(&file).metadata()?.len(); let mut result_copy: Result; let mut work = true; let copied_bytes = result; while work { { let _progress_handler = |info: super::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 = super::file::move_file_with_progress( &file, &path, &file_options, _progress_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 = TransitState::Exists; let user_decide = progress_handler(info_process); match user_decide { TransitProcessResult::Overwrite => { file_options.overwrite = true; } TransitProcessResult::OverwriteAll => { file_options.overwrite = true; options.overwrite = true; } TransitProcessResult::Skip => { is_remove = false; file_options.skip_exist = true; } TransitProcessResult::SkipAll => { is_remove = false; file_options.skip_exist = true; options.skip_exist = true; } TransitProcessResult::Retry => {} TransitProcessResult::ContinueOrAbort => { let err_msg = err.to_string(); err!(err_msg.as_str(), err.kind) } 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 = TransitState::Exists; let user_decide = progress_handler(info_process); match user_decide { TransitProcessResult::Overwrite => { err!("Overwrite denied for this situation!", ErrorKind::Other); } TransitProcessResult::OverwriteAll => { err!("Overwrite denied for this situation!", ErrorKind::Other); } TransitProcessResult::Skip => { is_remove = false; file_options.skip_exist = true; } TransitProcessResult::SkipAll => { file_options.skip_exist = true; options.skip_exist = true; } TransitProcessResult::Retry => {} TransitProcessResult::ContinueOrAbort => { let err_msg = err.to_string(); err!(err_msg.as_str(), err.kind) } 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) } }, } } } if is_remove { remove(from)?; } Ok(result) } /// Removes directory. /// /// # Example /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::dir::remove; /// /// remove("source/dir1"); // remove dir1 /// ``` pub fn remove>(path: P) -> Result<()> { if path.as_ref().exists() { Ok(remove_dir_all(path)?) } else { Ok(()) } } fs_extra-1.2.0/src/error.rs010064400017500001731000000110741372114267700140500ustar0000000000000000use 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 = ::std::result::Result; /// 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: 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 for Error { fn from(err: StripPrefixError) -> Error { Error::new( ErrorKind::StripPrefix(err), "StripPrefixError. Look inside for more details", ) } } impl From for Error { fn from(err: OsString) -> Error { Error::new( ErrorKind::OsString(err), "OsString. Look inside for more details", ) } } impl From 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()) } } fs_extra-1.2.0/src/file.rs010064400017500001731000000257121372114334700136350ustar0000000000000000use 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 skipe 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 } } } impl Default for CopyOptions { fn default() -> Self { CopyOptions::new() } } /// A structure which include information about the current status of the copy or move file. 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 rights 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(from: P, to: Q, options: &CopyOptions) -> Result where P: AsRef, Q: AsRef, { 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 \"{}\" is exist", msg); err!(&msg, ErrorKind::AlreadyExists); } } Ok(std::fs::copy(from, to)?) } /// Copies the contents of one file to another with recept information about process. /// 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 rights 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( from: P, to: Q, options: &CopyOptions, mut progress_handler: F, ) -> Result where P: AsRef, Q: AsRef, 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 \"{}\" is exist", 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) => { file_to.write(&mut buf[..n])?; copied_bytes = copied_bytes + n as u64; let data = TransitProcess { copied_bytes: 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 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 rights 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(from: P, to: Q, options: &CopyOptions) -> Result where P: AsRef, Q: AsRef, { 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 file from one place to another with recept information about process. /// 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 rights 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( from: P, to: Q, options: &CopyOptions, progress_handler: F, ) -> Result where P: AsRef, Q: AsRef, 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 rights to access `path`. /// /// # Example /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::file::remove; /// /// remove("foo.txt" )?; // Remove foo.txt /// /// ``` pub fn remove

(path: P) -> Result<()> where P: AsRef, { if path.as_ref().exists() { Ok(remove_file(path)?) } else { Ok(()) } } /// Read file content, placing him 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 rights 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 conent from foo.txt /// println!("{}", file_content); /// /// ``` pub fn read_to_string

(path: P) -> Result where P: AsRef, { 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 inside target 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 rights to access `path`. /// /// # Example /// ```rust,ignore /// extern crate fs_extra; /// use fs_extra::file::read_to_string; /// /// write_all("foo.txt", "conents" )?; // Create file foo.txt and send content inside /// /// ``` pub fn write_all

(path: P, content: &str) -> Result<()> where P: AsRef, { 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())?) } fs_extra-1.2.0/src/lib.rs010064400017500001731000000713671372114334700134730ustar0000000000000000macro_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 with files and folder. pub mod error; /// This module include extra methods for works 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 include extra methods for works with directories. /// /// One of the distinguishing features is receipt information /// about process work with directories 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 error::*; use std::path::Path; /// Copies list directories and files to another place using recursive method. This function will /// also copy the permission bits of the original files to destionation 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 rights 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(from: &[P], to: Q, options: &dir::CopyOptions) -> Result where P: AsRef, Q: AsRef, { 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 include information about the current status of the copy or move directory. pub struct TransitProcess { /// Copied bytes on this time for folder pub copied_bytes: u64, /// All the bytes which should to copy or move (dir size). pub total_bytes: u64, /// Copied bytes on this time for file. pub file_bytes_copied: u64, /// Size current copied file. pub file_total_bytes: u64, /// Name current copied file. pub file_name: String, /// Name current 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 list directories and files to another place using recursive method, with recept /// information about process. This function will also copy the permission bits of the /// original files to destionation 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 rights 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( from: &[P], to: Q, options: &dir::CopyOptions, mut progress_handler: F, ) -> Result where P: AsRef, Q: AsRef, F: FnMut(TransitProcess) -> dir::TransitProcessResult, { if options.content_only { err!( "Options 'content_only' not acccess 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, ..Default::default() }; 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; 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 list directories and files to another place using recursive method. This function will /// also copy the permission bits of the original files to destionation 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 rights 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(from_items: &[P], to: Q, options: &dir::CopyOptions) -> Result where P: AsRef, Q: AsRef, { if options.content_only { err!( "Options 'content_only' not acccess 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, ..Default::default() }; 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 list directories and files to another place using recursive method, with recept /// information about process. This function will also copy the permission bits of the /// original files to destionation 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 rights 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( from_items: &[P], to: Q, options: &dir::CopyOptions, mut progress_handler: F, ) -> Result where P: AsRef, Q: AsRef, F: FnMut(TransitProcess) -> dir::TransitProcessResult, { if options.content_only { err!( "Options 'content_only' not acccess 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, ..Default::default() }; 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; 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 list 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

(from_items: &[P]) -> Result<()> where P: AsRef, { for item in from_items { let item = item.as_ref(); if item.is_dir() { dir::remove(item)?; } else { file::remove(item)? } } Ok(()) } fs_extra-1.2.0/tests/dir.rs010064400017500001731000004652361372114244200140530ustar0000000000000000use std::collections::HashSet; use std::fs::read_dir; use std::path::{Path, PathBuf}; use std::sync::mpsc::{self, TryRecvError}; use std::thread; extern crate fs_extra; use fs_extra::dir::*; use fs_extra::error::*; fn files_eq(file1: P, file2: Q) -> bool where P: AsRef, Q: AsRef, { let content1 = fs_extra::file::read_to_string(file1).unwrap(); let content2 = fs_extra::file::read_to_string(file2).unwrap(); content1 == content2 } fn compare_dir(path_from: P, path_to: Q) -> bool where P: AsRef, Q: AsRef, { let mut path_to = path_to.as_ref().to_path_buf(); match path_from.as_ref().components().last() { None => panic!("Invalid folder from"), Some(dir_name) => { path_to.push(dir_name.as_os_str()); if !path_to.exists() { return false; } } } for entry in read_dir(&path_from).unwrap() { let entry = entry.unwrap(); let path = entry.path(); if path.is_dir() { if !compare_dir(path, &path_to) { return false; } } else { let mut path_to = path_to.to_path_buf(); match path.file_name() { None => panic!("No file name"), Some(file_name) => { path_to.push(file_name); if !path_to.exists() { return false; } else if !files_eq(&path, path_to.clone()) { return false; } } } } } true } const TEST_FOLDER: &'static str = "./tests/temp/dir"; #[test] fn it_create_all_work() { let mut test_dir = PathBuf::from(TEST_FOLDER); test_dir.push("it_create_all_work"); test_dir.push("sub_dir"); if test_dir.exists() { remove(&test_dir).unwrap(); } assert!(!test_dir.exists()); create_all(&test_dir, false).unwrap(); assert!(test_dir.exists()); } #[test] fn it_create_work() { let mut test_dir = PathBuf::from(TEST_FOLDER); test_dir.push("it_create_work"); if !test_dir.exists() { create_all(&test_dir, false).unwrap(); } assert!(test_dir.exists()); test_dir.push("sub_dir"); if test_dir.exists() { remove(&test_dir).unwrap(); } create(&test_dir, false).unwrap(); assert!(test_dir.exists()); } #[test] fn it_create_exist_folder() { let mut test_dir = PathBuf::from(TEST_FOLDER); test_dir.push("it_create_exist_folder"); test_dir.push("sub"); if test_dir.exists() { remove(&test_dir).unwrap(); } assert!(!test_dir.exists()); create_all(&test_dir, false).unwrap(); assert!(test_dir.exists()); let mut file_path = test_dir.clone(); file_path.push("test.txt"); assert!(!file_path.exists()); let content = "test_content"; fs_extra::file::write_all(&file_path, &content).unwrap(); assert!(file_path.exists()); match create(&test_dir, false) { Ok(_) => panic!("Should be error!"), Err(err) => match err.kind { ErrorKind::AlreadyExists => { assert!(test_dir.exists()); assert!(file_path.exists()); let new_content = fs_extra::file::read_to_string(file_path).unwrap(); assert_eq!(new_content, content); } _ => panic!("Wrong error"), }, } } #[test] fn it_create_erase_exist_folder() { let mut test_dir = PathBuf::from(TEST_FOLDER); test_dir.push("it_create_erase_exist_folder"); test_dir.push("sub"); if test_dir.exists() { remove(&test_dir).unwrap(); } assert!(!test_dir.exists()); create_all(&test_dir, true).unwrap(); assert!(test_dir.exists()); let mut file_path = test_dir.clone(); file_path.push("test.txt"); assert!(!file_path.exists()); fs_extra::file::write_all(&file_path, "test_content").unwrap(); assert!(file_path.exists()); create(&test_dir, true).unwrap(); assert!(test_dir.exists()); assert!(!file_path.exists()); } #[test] fn it_create_all_exist_folder() { let mut test_dir = PathBuf::from(TEST_FOLDER); test_dir.push("it_create_all_exist_folder"); test_dir.push("sub"); if test_dir.exists() { remove(&test_dir).unwrap(); } assert!(!test_dir.exists()); create_all(&test_dir, false).unwrap(); assert!(test_dir.exists()); let mut file_path = test_dir.clone(); file_path.push("test.txt"); assert!(!file_path.exists()); let content = "test_content"; fs_extra::file::write_all(&file_path, &content).unwrap(); assert!(file_path.exists()); create_all(&test_dir, false).unwrap(); assert!(test_dir.exists()); assert!(file_path.exists()); let new_content = fs_extra::file::read_to_string(file_path).unwrap(); assert_eq!(new_content, content); } #[test] fn it_create_all_erase_exist_folder() { let mut test_dir = PathBuf::from(TEST_FOLDER); test_dir.push("it_create_all_erase_exist_folder"); test_dir.push("sub"); if test_dir.exists() { remove(&test_dir).unwrap(); } assert!(!test_dir.exists()); create_all(&test_dir, true).unwrap(); assert!(test_dir.exists()); let mut file_path = test_dir.clone(); file_path.push("test.txt"); assert!(!file_path.exists()); fs_extra::file::write_all(&file_path, "test_content").unwrap(); assert!(file_path.exists()); create_all(&test_dir, true).unwrap(); assert!(test_dir.exists()); assert!(!file_path.exists()); } #[test] fn it_remove_work() { let mut test_dir = PathBuf::from(TEST_FOLDER); test_dir.push("it_remove_work"); test_dir.push("sub"); test_dir.push("second_sub"); create_all(&test_dir, true).unwrap(); assert!(test_dir.exists()); test_dir.pop(); test_dir.pop(); remove(&test_dir).unwrap(); assert!(!test_dir.exists()); } #[test] fn it_remove_not_exist() { let mut test_dir = PathBuf::from(TEST_FOLDER); test_dir.push("it_remove_not_exist"); test_dir.push("sub"); assert!(!test_dir.exists()); match remove(&test_dir) { Ok(_) => { assert!(!test_dir.exists()); } Err(err) => panic!(err.to_string()), } } #[test] fn it_copy_work() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_copy_work"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let options = CopyOptions::new(); let result = copy(&path_from, &path_to, &options).unwrap(); assert_eq!(16, result); assert!(path_to.exists()); assert!(path_from.exists()); assert!(compare_dir(&path_from, &path_to)); } #[test] fn it_copy_not_folder() { let mut path_from = PathBuf::from(TEST_FOLDER); path_from.push("it_copy_not_folder"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push("sub"); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let options = CopyOptions::new(); path_from.push("test.txt"); fs_extra::file::write_all(&path_from, "test").unwrap(); match copy(&path_from, &path_to, &options) { Err(err) => match err.kind { ErrorKind::InvalidFolder => { let wrong_path = format!( "Path \"{}\" is not a directory!", path_from.to_str().unwrap() ); assert_eq!(wrong_path, err.to_string()); } _ => { panic!("wrong error"); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_copy_source_not_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); path_from.push("it_copy_source_not_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push("sub"); assert!(!path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let options = CopyOptions::new(); match copy(&path_from, &path_to, &options) { Err(err) => match err.kind { ErrorKind::NotFound => { let wrong_path = format!( "Path \"{}\" does not exist or you don't have \ access!", path_from.to_str().unwrap() ); assert_eq!(wrong_path, err.to_string()); } _ => { panic!(format!("wrong error {}", err.to_string())); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_copy_exist_overwrite() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_copy_exist_overwrite"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); let same_file = "test.txt"; create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push(same_file); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut exist_path = path_to.clone(); exist_path.push(&test_name); create(&exist_path, true).unwrap(); assert!(exist_path.exists()); exist_path.push(same_file); let exist_content = "exist content"; assert_ne!(exist_content, content1); fs_extra::file::write_all(&exist_path, exist_content).unwrap(); assert!(exist_path.exists()); let mut options = CopyOptions::new(); options.overwrite = true; copy(&path_from, &path_to, &options).unwrap(); assert!(exist_path.exists()); assert!(files_eq(file1_path, exist_path)); assert!(path_to.exists()); assert!(compare_dir(&path_from, &path_to)); } #[test] fn it_copy_exist_not_overwrite() { let test_name = "sub"; let mut path_from = PathBuf::from(TEST_FOLDER); path_from.push("it_copy_exist_not_overwrite"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(test_name); let same_file = "test.txt"; create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push(same_file); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut exist_path = path_to.clone(); exist_path.push(&test_name); create(&exist_path, true).unwrap(); assert!(exist_path.exists()); exist_path.push(same_file); let exist_content = "exist content"; assert_ne!(exist_content, content1); fs_extra::file::write_all(&exist_path, exist_content).unwrap(); assert!(exist_path.exists()); let options = CopyOptions::new(); match copy(&path_from, &path_to, &options) { Err(err) => match err.kind { ErrorKind::AlreadyExists => { let wrong_path = format!("Path \"{}\" is exist", exist_path.to_str().unwrap()); assert_eq!(wrong_path, err.to_string()); } _ => { panic!(format!("wrong error {}", err.to_string())); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_copy_exist_skip_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_copy_exist_skip_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); let same_file = "test.txt"; create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push(same_file); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut exist_path = path_to.clone(); exist_path.push(&test_name); create(&exist_path, true).unwrap(); assert!(exist_path.exists()); exist_path.push(same_file); let exist_content = "exist content"; assert_ne!(exist_content, content1); fs_extra::file::write_all(&exist_path, exist_content).unwrap(); assert!(exist_path.exists()); let mut options = CopyOptions::new(); options.skip_exist = true; copy(&path_from, &path_to, &options).unwrap(); assert!(exist_path.exists()); assert!(!files_eq(file1_path, &exist_path)); assert_eq!( fs_extra::file::read_to_string(exist_path).unwrap(), exist_content ); assert!(path_to.exists()); assert!(!compare_dir(&path_from, &path_to)); } #[test] fn it_copy_exist_overwrite_and_skip_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_copy_exist_overwrite_and_skip_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); let same_file = "test.txt"; create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push(same_file); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut exist_path = path_to.clone(); exist_path.push(&test_name); create(&exist_path, true).unwrap(); assert!(exist_path.exists()); exist_path.push(same_file); let exist_content = "exist content"; assert_ne!(exist_content, content1); fs_extra::file::write_all(&exist_path, exist_content).unwrap(); assert!(exist_path.exists()); let mut options = CopyOptions::new(); options.overwrite = true; options.skip_exist = true; copy(&path_from, &path_to, &options).unwrap(); assert!(exist_path.exists()); assert!(files_eq(file1_path, exist_path)); assert!(path_to.exists()); assert!(compare_dir(&path_from, &path_to)); } #[test] fn it_copy_using_first_levels() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_using_first_levels"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.join("d_level_1")); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let d_level_4 = (d_level_3.0.join("d_level_4"), d_level_3.1.join("d_level_4")); let d_level_5 = (d_level_4.0.join("d_level_5"), d_level_4.1.join("d_level_5")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); let file4 = (d_level_4.0.join("file4.txt"), d_level_4.1.join("file4.txt")); let file5 = (d_level_5.0.join("file5.txt"), d_level_5.1.join("file5.txt")); create_all(&d_level_1.0, true).unwrap(); create_all(&d_level_2.0, true).unwrap(); create_all(&d_level_3.0, true).unwrap(); create_all(&d_level_4.0, true).unwrap(); create_all(&d_level_5.0, true).unwrap(); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(!d_level_1.1.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); assert!(!d_level_4.1.exists()); assert!(!d_level_5.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); let mut options = CopyOptions::new(); options.depth = 1; let result = copy(&d_level_1.0, path_to, &options).unwrap(); assert_eq!(8, result); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(d_level_1.1.exists()); assert!(d_level_2.1.exists()); assert!(!d_level_3.1.exists()); assert!(!d_level_4.1.exists()); assert!(!d_level_5.1.exists()); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); assert!(files_eq(&file1.0, &file1.1)); } #[test] fn it_copy_using_four_levels() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_using_four_levels"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.join("d_level_1")); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let d_level_4 = (d_level_3.0.join("d_level_4"), d_level_3.1.join("d_level_4")); let d_level_5 = (d_level_4.0.join("d_level_5"), d_level_4.1.join("d_level_5")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); let file4 = (d_level_4.0.join("file4.txt"), d_level_4.1.join("file4.txt")); let file5 = (d_level_5.0.join("file5.txt"), d_level_5.1.join("file5.txt")); create_all(&d_level_1.0, true).unwrap(); create_all(&d_level_2.0, true).unwrap(); create_all(&d_level_3.0, true).unwrap(); create_all(&d_level_4.0, true).unwrap(); create_all(&d_level_5.0, true).unwrap(); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(!d_level_1.1.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); assert!(!d_level_4.1.exists()); assert!(!d_level_5.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); let mut options = CopyOptions::new(); options.depth = 4; let result = copy(&d_level_1.0, path_to, &options).unwrap(); assert_eq!(32, result); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(d_level_1.1.exists()); assert!(d_level_2.1.exists()); assert!(d_level_3.1.exists()); assert!(d_level_4.1.exists()); assert!(d_level_5.1.exists()); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); assert!(files_eq(&file3.0, &file3.1)); assert!(files_eq(&file4.0, &file4.1)); } #[test] fn it_copy_content_only_option() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_content_only_option"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.clone()); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); create_all(&d_level_1.0, true).unwrap(); create_all(&d_level_2.0, true).unwrap(); create_all(&d_level_3.0, true).unwrap(); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); let mut options = CopyOptions::new(); options.content_only = true; let result = copy(&d_level_1.0, path_to, &options).unwrap(); assert_eq!(24, result); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_1.1.exists()); assert!(d_level_2.1.exists()); assert!(d_level_3.1.exists()); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); assert!(files_eq(&file3.0, &file3.1)); } #[test] fn it_copy_progress_work() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_copy_progress_work"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(15, result); assert!(path_to.exists()); assert!(compare_dir(&path_from, &path_to)); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "test2.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(15, process_info.total_bytes); } else if process_info.file_name == "test1.txt" { assert_eq!(7, process_info.file_total_bytes); assert_eq!(15, process_info.total_bytes); } else { panic!("Unknow file name!"); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_copy_with_progress_not_folder() { let mut path_from = PathBuf::from(TEST_FOLDER); path_from.push("it_copy_with_progress_not_folder"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push("sub"); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let options = CopyOptions::new(); path_from.push("test.txt"); fs_extra::file::write_all(&path_from, "test").unwrap(); let func_test = |process_info: TransitProcess| { match process_info.state { TransitState::NoAccess => {} _ => panic!("Error not should be!"), }; TransitProcessResult::ContinueOrAbort }; match copy_with_progress(&path_from, &path_to, &options, func_test) { Err(err) => match err.kind { ErrorKind::InvalidFolder => { let wrong_path = format!( "Path \"{}\" is not a directory!", path_from.to_str().unwrap() ); assert_eq!(wrong_path, err.to_string()); } _ => { panic!("wrong error"); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_copy_with_progress_work_dif_buf_size() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_copy_with_progress_work_dif_buf_size"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(16, result); assert!(path_to.exists()); assert!(compare_dir(&path_from, &path_to)); let mut options = CopyOptions::new(); options.buffer_size = 2; options.overwrite = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(16, result); assert!(path_to.exists()); assert!(compare_dir(&path_from, &path_to)); }).join(); for i in 1..5 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i * 2, process_info.file_bytes_copied); assert_eq!(i * 2, process_info.copied_bytes); assert_eq!(8, process_info.file_total_bytes); assert_eq!(16, process_info.total_bytes); } for i in 1..5 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i * 2 + 8, process_info.copied_bytes); assert_eq!(i * 2, process_info.file_bytes_copied); assert_eq!(8, process_info.file_total_bytes); assert_eq!(16, process_info.total_bytes); } match result { Ok(_) => {} Err(err) => panic!(err), } }).join(); for i in 1..9 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i, process_info.file_bytes_copied); assert_eq!(i, process_info.copied_bytes); assert_eq!(8, process_info.file_total_bytes); assert_eq!(16, process_info.total_bytes); } for i in 1..9 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i + 8, process_info.copied_bytes); assert_eq!(i, process_info.file_bytes_copied); assert_eq!(8, process_info.file_total_bytes); assert_eq!(16, process_info.total_bytes); } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_copy_with_progress_source_not_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); path_from.push("it_copy_with_progress_source_not_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push("sub"); assert!(!path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let options = CopyOptions::new(); let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; match copy_with_progress(&path_from, &path_to, &options, func_test) { Err(err) => match err.kind { ErrorKind::NotFound => { let wrong_path = format!( "Path \"{}\" does not exist or you don't \ have access!", path_from.to_str().unwrap() ); assert_eq!(wrong_path, err.to_string()); } _ => { panic!(format!("wrong error {}", err.to_string())); } }, Ok(_) => { panic!("should be error"); } } }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => {} _ => panic!("should be error"), } } #[test] fn it_copy_with_progress_exist_overwrite() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_copy_with_progress_exist_overwrite"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); copy(&path_from, &path_to, &options).unwrap(); fs_extra::file::write_all(&file2_path, "another conntent").unwrap(); options.buffer_size = 1; options.overwrite = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(23, result); assert!(path_to.exists()); assert!(compare_dir(&path_from, &path_to)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_copy_with_progress_exist_not_overwrite() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_copy_with_progress_exist_not_overwrite"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); copy(&path_from, &path_to, &options).unwrap(); options.buffer_size = 1; let func_test = |process_info: TransitProcess| { match process_info.state { TransitState::Exists => {} _ => panic!("Error not should be!"), }; TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&path_from, &path_to, &options, func_test); match result { Ok(_) => panic!("Should be error!"), Err(err) => match err.kind { ErrorKind::AlreadyExists => {} _ => panic!("Wrong wrror"), }, } } #[test] fn it_copy_with_progress_exist_skip_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_copy_with_progress_exist_skip_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); copy(&path_from, &path_to, &options).unwrap(); fs_extra::file::write_all(&file2_path, "another conntent").unwrap(); options.buffer_size = 1; options.skip_exist = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(0, result); assert!(path_to.exists()); assert!(!compare_dir(&path_from, &path_to)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => {} _ => panic!("should be error"), } } #[test] fn it_copy_with_progress_exist_overwrite_and_skip_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_copy_with_progress_exist_overwrite_and_skip_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); copy(&path_from, &path_to, &options).unwrap(); fs_extra::file::write_all(&file2_path, "another conntent").unwrap(); options.buffer_size = 1; options.overwrite = true; options.skip_exist = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(23, result); assert!(path_to.exists()); assert!(compare_dir(&path_from, &path_to)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.recv().unwrap(); } #[test] fn it_copy_with_progress_using_first_levels() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_using_first_levels"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.join("d_level_1")); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let d_level_4 = (d_level_3.0.join("d_level_4"), d_level_3.1.join("d_level_4")); let d_level_5 = (d_level_4.0.join("d_level_5"), d_level_4.1.join("d_level_5")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); let file4 = (d_level_4.0.join("file4.txt"), d_level_4.1.join("file4.txt")); let file5 = (d_level_5.0.join("file5.txt"), d_level_5.1.join("file5.txt")); create_all(&d_level_1.0, true).unwrap(); create_all(&d_level_2.0, true).unwrap(); create_all(&d_level_3.0, true).unwrap(); create_all(&d_level_4.0, true).unwrap(); create_all(&d_level_5.0, true).unwrap(); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(!d_level_1.1.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); assert!(!d_level_4.1.exists()); assert!(!d_level_5.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); let mut options = CopyOptions::new(); options.depth = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&d_level_1.0, &path_to, &options, func_test).unwrap(); assert_eq!(8, result); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(d_level_1.1.exists()); assert!(d_level_2.1.exists()); assert!(!d_level_3.1.exists()); assert!(!d_level_4.1.exists()); assert!(!d_level_5.1.exists()); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); assert!(files_eq(&file1.0, &file1.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_copy_with_progress_using_four_levels() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_using_four_levels"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.join("d_level_1")); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let d_level_4 = (d_level_3.0.join("d_level_4"), d_level_3.1.join("d_level_4")); let d_level_5 = (d_level_4.0.join("d_level_5"), d_level_4.1.join("d_level_5")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); let file4 = (d_level_4.0.join("file4.txt"), d_level_4.1.join("file4.txt")); let file5 = (d_level_5.0.join("file5.txt"), d_level_5.1.join("file5.txt")); create_all(&d_level_1.0, true).unwrap(); create_all(&d_level_2.0, true).unwrap(); create_all(&d_level_3.0, true).unwrap(); create_all(&d_level_4.0, true).unwrap(); create_all(&d_level_5.0, true).unwrap(); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(!d_level_1.1.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); assert!(!d_level_4.1.exists()); assert!(!d_level_5.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); let mut options = CopyOptions::new(); options.depth = 4; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&d_level_1.0, &path_to, &options, func_test).unwrap(); assert_eq!(32, result); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(d_level_1.1.exists()); assert!(d_level_2.1.exists()); assert!(d_level_3.1.exists()); assert!(d_level_4.1.exists()); assert!(d_level_5.1.exists()); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); assert!(files_eq(&file3.0, &file3.1)); assert!(files_eq(&file4.0, &file4.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_copy_with_progress_content_only_option() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_content_only_option"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.clone()); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); create_all(&d_level_1.0, true).unwrap(); create_all(&d_level_2.0, true).unwrap(); create_all(&d_level_3.0, true).unwrap(); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); let mut options = CopyOptions::new(); options.content_only = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&d_level_1.0, &path_to, &options, func_test).unwrap(); assert_eq!(24, result); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_1.1.exists()); assert!(d_level_2.1.exists()); assert!(d_level_3.1.exists()); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); assert!(files_eq(&file3.0, &file3.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_copy_inside_work_target_dir_not_exist() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join("it_copy_inside_work_target_dir_not_exist"); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); create_all(&root_dir1_sub, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content2").unwrap(); if root_dir2.exists() { remove(&root_dir2).unwrap(); } assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(!root_dir2.exists()); assert!(file1.exists()); assert!(file2.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; let result = copy(&root_dir1, &root_dir2, &options).unwrap(); assert_eq!(16, result); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(compare_dir_recursively(&root_dir1, &root_dir2)); } #[test] fn it_copy_inside_work_target_dir_exist_with_no_source_dir_named_sub_dir() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join("it_copy_inside_work_target_dir_exist_with_no_source_dir_named_sub_dir"); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let root_dir2_dir1 = root_dir2.join("dir1"); let root_dir2_dir3 = root_dir2.join("dir3"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); let file3 = root_dir2_dir3.join("file3.txt"); create_all(&root_dir1_sub, true).unwrap(); create_all(&root_dir2_dir3, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content2").unwrap(); fs_extra::file::write_all(&file3, "content3").unwrap(); if root_dir2_dir1.exists() { remove(&root_dir2_dir1).unwrap(); } assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(!root_dir2_dir1.exists()); assert!(root_dir2_dir3.exists()); assert!(file1.exists()); assert!(file2.exists()); assert!(file3.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; let result = copy(&root_dir1, &root_dir2, &options).unwrap(); assert_eq!(16, result); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir3.exists()); assert!(compare_dir(&root_dir1, &root_dir2)); } #[test] fn it_copy_inside_work_target_dir_exist_with_source_dir_exist() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join("it_copy_inside_work_target_dir_exist_with_source_dir_exist"); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let root_dir2_dir1 = root_dir2.join("dir1"); let root_dir2_dir1_sub = root_dir2_dir1.join("sub"); let root_dir2_dir3 = root_dir2.join("dir3"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); let file3 = root_dir2_dir3.join("file3.txt"); let old_file1 = root_dir2_dir1.join("file1.txt"); let old_file2 = root_dir2_dir1_sub.join("file2.txt"); create_all(&root_dir1_sub, true).unwrap(); create_all(&root_dir2_dir3, true).unwrap(); create_all(&root_dir2_dir1, true).unwrap(); create_all(&root_dir2_dir1_sub, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content2").unwrap(); fs_extra::file::write_all(&file3, "content3").unwrap(); fs_extra::file::write_all(&old_file1, "old_content1").unwrap(); fs_extra::file::write_all(&old_file2, "old_content2").unwrap(); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); assert!(file1.exists()); assert!(file2.exists()); assert!(file3.exists()); assert!(old_file1.exists()); assert!(old_file2.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; match copy(&root_dir1, &root_dir2, &options) { Err(err) => match err.kind { ErrorKind::AlreadyExists => { assert_eq!(1, 1); } _ => { panic!(format!("wrong error {}", err.to_string())); } }, Ok(_) => { panic!("should be error"); } } options.overwrite = true; let result = copy(&root_dir1, &root_dir2, &options).unwrap(); assert_eq!(16, result); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); assert!(compare_dir(&root_dir1, &root_dir2)); } // The compare_dir method assumes that the folder `path_to` must have a sub folder named the last component of the `path_from`. // In order to compare two folders with different name but share the same structure, rewrite a new compare method to do that! fn compare_dir_recursively(path_from: P, path_to: Q) -> bool where P: AsRef, Q: AsRef, { let path_to = path_to.as_ref().to_path_buf(); for entry in read_dir(&path_from).unwrap() { let entry = entry.unwrap(); let path = entry.path(); if path.is_dir() { match path.components().last() { None => panic!("Invalid folder from"), Some(dir_name) => { let mut target_dir = path_to.to_path_buf(); target_dir.push(dir_name.as_os_str()); if !compare_dir_recursively(path.clone(), &target_dir) { return false; } } } } else { let mut target_file = path_to.to_path_buf(); match path.file_name() { None => panic!("No file name"), Some(file_name) => { target_file.push(file_name); if !target_file.exists() { return false; } else if !files_eq(&path, target_file.clone()) { return false; } } } } } true } #[test] fn it_move_work() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_move_work"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let options = CopyOptions::new(); let result = move_dir(&path_from, &path_to, &options).unwrap(); assert_eq!(16, result); assert!(path_to.exists()); assert!(!path_from.exists()); } #[test] fn it_move_not_folder() { let mut path_from = PathBuf::from(TEST_FOLDER); path_from.push("it_move_not_folder"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push("sub"); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let options = CopyOptions::new(); path_from.push("test.txt"); fs_extra::file::write_all(&path_from, "test").unwrap(); match move_dir(&path_from, &path_to, &options) { Err(err) => match err.kind { ErrorKind::InvalidFolder => { let wrong_path = format!( "Path \"{}\" is not a directory or you don't have \ access!", path_from.to_str().unwrap() ); assert_eq!(wrong_path, err.to_string()); } _ => { panic!("wrong error"); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_move_source_not_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); path_from.push("it_move_source_not_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push("sub"); assert!(!path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let options = CopyOptions::new(); match move_dir(&path_from, &path_to, &options) { Err(err) => match err.kind { ErrorKind::NotFound => { let wrong_path = format!("Path \"{}\" does not exist", path_from.to_str().unwrap()); assert_eq!(wrong_path, err.to_string()); } _ => { panic!(format!("wrong error {}", err.to_string())); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_move_exist_overwrite() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_move_exist_overwrite"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); let same_file = "test.txt"; create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push(same_file); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut exist_path = path_to.clone(); exist_path.push(&test_name); create(&exist_path, true).unwrap(); assert!(exist_path.exists()); exist_path.push(same_file); let exist_content = "exist content"; assert_ne!(exist_content, content1); fs_extra::file::write_all(&exist_path, exist_content).unwrap(); assert!(exist_path.exists()); let mut options = CopyOptions::new(); options.overwrite = true; move_dir(&path_from, &path_to, &options).unwrap(); assert!(exist_path.exists()); assert!(path_to.exists()); assert!(!path_from.exists()); } #[test] fn it_move_exist_not_overwrite() { let test_name = "sub"; let mut path_from = PathBuf::from(TEST_FOLDER); path_from.push("it_move_exist_not_overwrite"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(test_name); let same_file = "test.txt"; create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push(same_file); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut exist_path = path_to.clone(); exist_path.push(&test_name); create(&exist_path, true).unwrap(); assert!(exist_path.exists()); exist_path.push(same_file); let exist_content = "exist content"; assert_ne!(exist_content, content1); fs_extra::file::write_all(&exist_path, exist_content).unwrap(); assert!(exist_path.exists()); let options = CopyOptions::new(); match move_dir(&path_from, &path_to, &options) { Err(err) => match err.kind { ErrorKind::AlreadyExists => { let wrong_path = format!("Path \"{}\" is exist", exist_path.to_str().unwrap()); assert_eq!(wrong_path, err.to_string()); } _ => { panic!(format!("wrong error {}", err.to_string())); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_move_exist_skip_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_move_exist_skip_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); let same_file = "test.txt"; create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push(same_file); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut exist_path = path_to.clone(); exist_path.push(&test_name); create(&exist_path, true).unwrap(); assert!(exist_path.exists()); exist_path.push(same_file); let exist_content = "exist content"; assert_ne!(exist_content, content1); fs_extra::file::write_all(&exist_path, exist_content).unwrap(); assert!(exist_path.exists()); let mut options = CopyOptions::new(); options.skip_exist = true; move_dir(&path_from, &path_to, &options).unwrap(); assert!(exist_path.exists()); assert_eq!( fs_extra::file::read_to_string(exist_path).unwrap(), exist_content ); assert!(path_to.exists()); } #[test] fn it_move_exist_overwrite_and_skip_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_move_exist_overwrite_and_skip_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); let same_file = "test.txt"; create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push(same_file); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut exist_path = path_to.clone(); exist_path.push(&test_name); create(&exist_path, true).unwrap(); assert!(exist_path.exists()); exist_path.push(same_file); let exist_content = "exist content"; assert_ne!(exist_content, content1); fs_extra::file::write_all(&exist_path, exist_content).unwrap(); assert!(exist_path.exists()); let mut options = CopyOptions::new(); options.overwrite = true; options.skip_exist = true; move_dir(&path_from, &path_to, &options).unwrap(); assert!(exist_path.exists()); assert!(path_to.exists()); assert!(!path_from.exists()); } #[test] fn it_move_inside_work_target_dir_not_exist() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join("it_move_inside_work_target_dir_not_exist"); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); create_all(&root_dir1_sub, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content2").unwrap(); if root_dir2.exists() { remove(&root_dir2).unwrap(); } assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(!root_dir2.exists()); assert!(file1.exists()); assert!(file2.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; let result = move_dir(&root_dir1, &root_dir2, &options).unwrap(); assert_eq!(16, result); assert!(!root_dir1.exists()); let root_dir2_sub = root_dir2.join("sub"); let root_dir2_file1 = root_dir2.join("file1.txt"); let root_dir2_sub_file2 = root_dir2_sub.join("file2.txt"); assert!(root_dir2.exists()); assert!(root_dir2_sub.exists()); assert!(root_dir2_file1.exists()); assert!(root_dir2_sub_file2.exists()); } #[test] fn it_move_inside_work_target_dir_exist_with_no_source_dir_named_sub_dir() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join("it_move_inside_work_target_dir_exist_with_no_source_dir_named_sub_dir"); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let root_dir2_dir1 = root_dir2.join("dir1"); let root_dir2_dir3 = root_dir2.join("dir3"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); let file3 = root_dir2_dir3.join("file3.txt"); create_all(&root_dir1_sub, true).unwrap(); create_all(&root_dir2_dir3, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content2").unwrap(); fs_extra::file::write_all(&file3, "content3").unwrap(); if root_dir2_dir1.exists() { remove(&root_dir2_dir1).unwrap(); } assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(!root_dir2_dir1.exists()); assert!(root_dir2_dir3.exists()); assert!(file1.exists()); assert!(file2.exists()); assert!(file3.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; let result = move_dir(&root_dir1, &root_dir2, &options).unwrap(); assert_eq!(16, result); assert!(!root_dir1.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir3.exists()); let root_dir2_dir1_file1 = root_dir2_dir1.join("file1.txt"); let root_dir2_dir1_sub = root_dir2_dir1.join("sub"); let root_dir2_dir1_sub_file2 = root_dir2_dir1_sub.join("file2.txt"); let root_dir2_dir3_file3 = root_dir2_dir3.join("file3.txt"); assert!(root_dir2_dir1_file1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir1_sub_file2.exists()); assert!(root_dir2_dir3_file3.exists()); } #[test] fn it_move_inside_work_target_dir_exist_with_source_dir_exist() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join("it_move_inside_work_target_dir_exist_with_source_dir_exist"); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let root_dir2_dir1 = root_dir2.join("dir1"); let root_dir2_dir1_sub = root_dir2_dir1.join("sub"); let root_dir2_dir3 = root_dir2.join("dir3"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); let file3 = root_dir2_dir3.join("file3.txt"); let old_file1 = root_dir2_dir1.join("file1.txt"); let old_file2 = root_dir2_dir1_sub.join("file2.txt"); create_all(&root_dir1_sub, true).unwrap(); create_all(&root_dir2_dir3, true).unwrap(); create_all(&root_dir2_dir1, true).unwrap(); create_all(&root_dir2_dir1_sub, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content2").unwrap(); fs_extra::file::write_all(&file3, "content3").unwrap(); fs_extra::file::write_all(&old_file1, "old_content1").unwrap(); fs_extra::file::write_all(&old_file2, "old_content2").unwrap(); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); assert!(file1.exists()); assert!(file2.exists()); assert!(file3.exists()); assert!(old_file1.exists()); assert!(old_file2.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; match copy(&root_dir1, &root_dir2, &options) { Err(err) => match err.kind { ErrorKind::AlreadyExists => { assert_eq!(1, 1); } _ => { panic!(format!("wrong error {}", err.to_string())); } }, Ok(_) => { panic!("should be error"); } } options.overwrite = true; let result = move_dir(&root_dir1, &root_dir2, &options).unwrap(); assert_eq!(16, result); assert!(!root_dir1.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); let root_dir2_dir1_file1 = root_dir2_dir1.join("file1.txt"); let root_dir2_dir1_sub_file2 = root_dir2_dir1_sub.join("file2.txt"); let root_dir2_dir3_file3 = root_dir2_dir3.join("file3.txt"); assert!(root_dir2_dir1_file1.exists()); assert!(root_dir2_dir1_sub_file2.exists()); assert!(root_dir2_dir3_file3.exists()); } #[test] fn it_move_content_only_option() { let test_dir = Path::new(TEST_FOLDER).join("it_move_content_only_option"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.clone()); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); create_all(&d_level_1.0, true).unwrap(); create_all(&d_level_2.0, true).unwrap(); create_all(&d_level_3.0, true).unwrap(); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); let mut options = CopyOptions::new(); options.content_only = true; let result = move_dir(&d_level_1.0, path_to, &options).unwrap(); assert_eq!(24, result); assert!(!d_level_1.0.exists()); assert!(!d_level_2.0.exists()); assert!(!d_level_3.0.exists()); assert!(d_level_1.1.exists()); assert!(d_level_2.1.exists()); assert!(d_level_3.1.exists()); assert!(!file1.0.exists()); assert!(!file2.0.exists()); assert!(!file3.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); } #[test] fn it_move_progress_work() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_move_progress_work"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = move_dir_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(15, result); assert!(path_to.exists()); assert!(!path_from.exists()); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "test2.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(15, process_info.total_bytes); } else if process_info.file_name == "test1.txt" { assert_eq!(7, process_info.file_total_bytes); assert_eq!(15, process_info.total_bytes); } else { panic!("Unknow file name!"); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_move_with_progress_not_folder() { let mut path_from = PathBuf::from(TEST_FOLDER); path_from.push("it_move_with_progress_not_folder"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push("sub"); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let options = CopyOptions::new(); path_from.push("test.txt"); fs_extra::file::write_all(&path_from, "test").unwrap(); let func_test = |process_info: TransitProcess| { match process_info.state { TransitState::NoAccess => {} _ => panic!("Error not should be!"), }; TransitProcessResult::ContinueOrAbort }; match move_dir_with_progress(&path_from, &path_to, &options, func_test) { Err(err) => match err.kind { ErrorKind::InvalidFolder => { let wrong_path = format!( "Path \"{}\" is not a directory!", path_from.to_str().unwrap() ); assert_eq!(wrong_path, err.to_string()); } _ => { panic!("wrong error"); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_move_with_progress_work_dif_buf_size() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_move_with_progress_work_dif_buf_size"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = move_dir_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(16, result); assert!(path_to.exists()); assert!(!path_from.exists()); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content1"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); options.buffer_size = 2; options.overwrite = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = move_dir_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(16, result); assert!(path_to.exists()); assert!(!path_from.exists()); }).join(); for i in 1..5 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i * 2, process_info.file_bytes_copied); assert_eq!(i * 2, process_info.copied_bytes); assert_eq!(8, process_info.file_total_bytes); assert_eq!(16, process_info.total_bytes); } for i in 1..5 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i * 2 + 8, process_info.copied_bytes); assert_eq!(i * 2, process_info.file_bytes_copied); assert_eq!(8, process_info.file_total_bytes); assert_eq!(16, process_info.total_bytes); } match result { Ok(_) => {} Err(err) => panic!(err), } }).join(); for i in 1..9 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i, process_info.file_bytes_copied); assert_eq!(i, process_info.copied_bytes); assert_eq!(8, process_info.file_total_bytes); assert_eq!(16, process_info.total_bytes); } for i in 1..9 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i + 8, process_info.copied_bytes); assert_eq!(i, process_info.file_bytes_copied); assert_eq!(8, process_info.file_total_bytes); assert_eq!(16, process_info.total_bytes); } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_move_with_progress_source_not_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); path_from.push("it_move_with_progress_source_not_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push("sub"); assert!(!path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let options = CopyOptions::new(); let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; match move_dir_with_progress(&path_from, &path_to, &options, func_test) { Err(err) => match err.kind { ErrorKind::NotFound => { let wrong_path = format!( "Path \"{}\" does not exist or you don't \ have access!", path_from.to_str().unwrap() ); assert_eq!(wrong_path, err.to_string()); } _ => { panic!(format!("wrong error {}", err.to_string())); } }, Ok(_) => { panic!("should be error"); } } }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => {} _ => panic!("should be error"), } } #[test] fn it_move_with_progress_exist_overwrite() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_move_with_progress_exist_overwrite"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); copy(&path_from, &path_to, &options).unwrap(); fs_extra::file::write_all(&file2_path, "another conntent").unwrap(); options.buffer_size = 1; options.overwrite = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = move_dir_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(23, result); assert!(path_to.exists()); assert!(!path_from.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.recv().unwrap(); } #[test] fn it_move_with_progress_exist_not_overwrite() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_move_with_progress_exist_not_overwrite"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); copy(&path_from, &path_to, &options).unwrap(); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = move_dir_with_progress(&path_from, &path_to, &options, func_test); match result { Ok(_) => panic!("Should be error!"), Err(err) => match err.kind { ErrorKind::AlreadyExists => {} _ => panic!("Wrong wrror"), }, } }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => { panic!("Error not should be!"); } _ => {} } } #[test] fn it_move_with_progress_exist_skip_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_move_with_progress_exist_skip_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); copy(&path_from, &path_to, &options).unwrap(); fs_extra::file::write_all(&file2_path, "another conntent").unwrap(); options.buffer_size = 1; options.skip_exist = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = move_dir_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(0, result); assert!(path_from.exists()); assert!(path_to.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => {} _ => panic!("should be error"), } } #[test] fn it_move_with_progress_exist_overwrite_and_skip_exist() { let mut path_from = PathBuf::from(TEST_FOLDER); let test_name = "sub"; path_from.push("it_move_with_progress_exist_overwrite_and_skip_exist"); let mut path_to = path_from.clone(); path_to.push("out"); path_from.push(&test_name); create_all(&path_from, true).unwrap(); assert!(path_from.exists()); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); let mut file1_path = path_from.clone(); file1_path.push("test1.txt"); let content1 = "content"; fs_extra::file::write_all(&file1_path, &content1).unwrap(); assert!(file1_path.exists()); let mut sub_dir_path = path_from.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2_path = sub_dir_path.clone(); file2_path.push("test2.txt"); let content2 = "content2"; fs_extra::file::write_all(&file2_path, &content2).unwrap(); assert!(file2_path.exists()); let mut options = CopyOptions::new(); copy(&path_from, &path_to, &options).unwrap(); fs_extra::file::write_all(&file2_path, "another conntent").unwrap(); options.buffer_size = 1; options.overwrite = true; options.skip_exist = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = move_dir_with_progress(&path_from, &path_to, &options, func_test).unwrap(); assert_eq!(23, result); assert!(path_to.exists()); assert!(!path_from.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.recv().unwrap(); } #[test] fn it_get_folder_size() { let mut path = PathBuf::from(TEST_FOLDER); path.push("it_get_folder_size"); path.push("dir"); create_all(&path, true).unwrap(); assert!(path.exists()); let mut file1 = path.clone(); file1.push("test1.txt"); fs_extra::file::write_all(&file1, "content1").unwrap(); assert!(file1.exists()); let mut sub_dir_path = path.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2 = sub_dir_path.clone(); file2.push("test2.txt"); fs_extra::file::write_all(&file2, "content2").unwrap(); assert!(file2.exists()); let result = get_size(&path).unwrap(); assert_eq!(16, result); } #[test] fn it_get_file_size() { let mut path = PathBuf::from(TEST_FOLDER); path.push("it_get_file_size"); create_all(&path, true).unwrap(); assert!(path.exists()); let mut file = path.clone(); file.push("test1.txt"); fs_extra::file::write_all(&file, "content").unwrap(); assert!(file.exists()); let result = get_size(&path).unwrap(); assert_eq!(7, result); } #[test] fn it_get_size_not_found() { let mut path = PathBuf::from(TEST_FOLDER); path.push("it_get_size_not_found"); assert!(!path.exists()); match get_size(&path) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::NotFound => {} _ => panic!("Wrong error!"), }, }; } #[test] fn it_get_dir_content() { let mut path = PathBuf::from(TEST_FOLDER); path.push("it_get_dir_content"); path.push("dir"); create_all(&path, true).unwrap(); assert!(path.exists()); let mut file1 = path.clone(); file1.push("test1.txt"); fs_extra::file::write_all(&file1, "content1").unwrap(); assert!(file1.exists()); let mut sub_dir_path = path.clone(); sub_dir_path.push("sub"); create(&sub_dir_path, true).unwrap(); let mut file2 = sub_dir_path.clone(); file2.push("test2.txt"); fs_extra::file::write_all(&file2, "content2").unwrap(); assert!(file2.exists()); let result = get_dir_content(&path).unwrap(); assert_eq!(16, result.dir_size); assert_eq!(2, result.files.len()); assert_eq!(2, result.directories.len()); let dir1 = file1.parent().unwrap().to_str().unwrap().to_string(); let dir2 = file2.parent().unwrap().to_str().unwrap().to_string(); let file1 = file1.to_str().unwrap().to_string(); let file2 = file2.to_str().unwrap().to_string(); let mut files_correct = true; for file in result.files { if file != file1 && file != file2 { files_correct = false; } } assert!(files_correct); let mut directories_correct = true; for dir in result.directories { if dir != dir1 && dir != dir2 { directories_correct = false; } } assert!(directories_correct); } #[test] fn it_get_dir_content_many_levels() { let test_dir = Path::new(TEST_FOLDER).join("it_get_dir_content_many_levels"); let d_level_1 = test_dir.join("d_level_1"); let d_level_2 = d_level_1.join("d_level_2"); let d_level_3 = d_level_2.join("d_level_3"); let d_level_4 = d_level_3.join("d_level_4"); let d_level_5 = d_level_4.join("d_level_5"); let file1 = d_level_1.join("file1.txt"); let file2 = d_level_2.join("file2.txt"); let file3 = d_level_3.join("file3.txt"); let file4 = d_level_4.join("file4.txt"); let file5 = d_level_5.join("file5.txt"); create_all(&d_level_1, true).unwrap(); create_all(&d_level_2, true).unwrap(); create_all(&d_level_3, true).unwrap(); create_all(&d_level_4, true).unwrap(); create_all(&d_level_5, true).unwrap(); assert!(&d_level_1.exists()); assert!(&d_level_2.exists()); assert!(&d_level_3.exists()); assert!(&d_level_4.exists()); assert!(&d_level_5.exists()); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content2").unwrap(); fs_extra::file::write_all(&file3, "content3").unwrap(); fs_extra::file::write_all(&file4, "content4").unwrap(); fs_extra::file::write_all(&file5, "content5").unwrap(); let mut options = DirOptions::new(); let result = get_dir_content2(&d_level_1, &options).unwrap(); assert_eq!(40, result.dir_size); assert_eq!(5, result.files.len()); assert_eq!(5, result.directories.len()); let mut directories = Vec::new(); directories.push(file1.parent().unwrap().to_str().unwrap().to_string()); directories.push(file2.parent().unwrap().to_str().unwrap().to_string()); directories.push(file3.parent().unwrap().to_str().unwrap().to_string()); directories.push(file4.parent().unwrap().to_str().unwrap().to_string()); directories.push(file5.parent().unwrap().to_str().unwrap().to_string()); let mut files = Vec::new(); files.push(file1.to_str().unwrap().to_string()); files.push(file2.to_str().unwrap().to_string()); files.push(file3.to_str().unwrap().to_string()); files.push(file4.to_str().unwrap().to_string()); files.push(file5.to_str().unwrap().to_string()); let mut files_correct = true; for file in result.files { if !files.contains(&file) { files_correct = false; } } assert!(files_correct); let mut directories_correct = true; for dir in result.directories { if !directories.contains(&dir) { directories_correct = false; } } assert!(directories_correct); // first level options.depth = 1; let result = get_dir_content2(&d_level_1, &options).unwrap(); assert_eq!(8, result.dir_size); assert_eq!(1, result.files.len()); assert_eq!(2, result.directories.len()); files_correct = true; for file in &result.files { if !files.contains(&file) { files_correct = false; } } assert!(files_correct); assert!(result.files.contains(&file1.to_str().unwrap().to_string())); directories_correct = true; for dir in &result.directories { if !directories.contains(&dir) { directories_correct = false; } } assert!(directories_correct); assert!( result .directories .contains(&file1.parent().unwrap().to_str().unwrap().to_string(),) ); assert!( result .directories .contains(&file2.parent().unwrap().to_str().unwrap().to_string(),) ); // fourth level options.depth = 4; let result = get_dir_content2(&d_level_1, &options).unwrap(); assert_eq!(32, result.dir_size); assert_eq!(4, result.files.len()); assert_eq!(5, result.directories.len()); files_correct = true; for file in &result.files { if !files.contains(&file) { files_correct = false; } } assert!(files_correct); assert!(result.files.contains(&file1.to_str().unwrap().to_string())); assert!(result.files.contains(&file2.to_str().unwrap().to_string())); assert!(result.files.contains(&file3.to_str().unwrap().to_string())); assert!(result.files.contains(&file4.to_str().unwrap().to_string())); directories_correct = true; for dir in &result.directories { if !directories.contains(&dir) { directories_correct = false; } } assert!(directories_correct); assert!( result .directories .contains(&file1.parent().unwrap().to_str().unwrap().to_string(),) ); assert!( result .directories .contains(&file2.parent().unwrap().to_str().unwrap().to_string(),) ); assert!( result .directories .contains(&file3.parent().unwrap().to_str().unwrap().to_string(),) ); assert!( result .directories .contains(&file4.parent().unwrap().to_str().unwrap().to_string(),) ); assert!( result .directories .contains(&file5.parent().unwrap().to_str().unwrap().to_string(),) ); } #[test] fn it_get_dir_content_path_file() { let mut path = PathBuf::from(TEST_FOLDER); path.push("it_get_dir_content_path_file"); create_all(&path, true).unwrap(); assert!(path.exists()); let mut file = path.clone(); file.push("test1.txt"); fs_extra::file::write_all(&file, "content1").unwrap(); assert!(file.exists()); let result = get_dir_content(&file).unwrap(); assert_eq!(8, result.dir_size); assert_eq!(1, result.files.len()); assert_eq!(0, result.directories.len()); assert_eq!(file.to_str().unwrap().to_string(), result.files[0]); } #[test] fn it_get_dir_content_not_found() { let mut path = PathBuf::from(TEST_FOLDER); path.push("it_get_dir_content_not_found"); assert!(!path.exists()); match get_dir_content(&path) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::NotFound => {} _ => panic!("Wrong error!"), }, } } #[test] fn it_details_item_dir() { let test_dir = Path::new(TEST_FOLDER).join("it_details_item_dir"); create_all(&test_dir, true).unwrap(); assert!(test_dir.exists()); let mut config = HashSet::new(); config.insert(DirEntryAttr::Name); config.insert(DirEntryAttr::Ext); config.insert(DirEntryAttr::FullName); config.insert(DirEntryAttr::Path); config.insert(DirEntryAttr::DosPath); config.insert(DirEntryAttr::Size); config.insert(DirEntryAttr::IsDir); config.insert(DirEntryAttr::IsFile); config.insert(DirEntryAttr::Modified); config.insert(DirEntryAttr::Accessed); let item = get_details_entry(test_dir, &config).unwrap(); assert_eq!(10, item.len()); let mut fields = 0; if let Some(name) = item.get(&DirEntryAttr::Name) { if let &DirEntryValue::String(ref name) = name { assert_eq!("it_details_item_dir", name); fields += 1; } } if let Some(ext) = item.get(&DirEntryAttr::Ext) { if let &DirEntryValue::String(ref ext) = ext { assert_eq!("", ext); fields += 1; } } if let Some(fname) = item.get(&DirEntryAttr::FullName) { if let &DirEntryValue::String(ref fname) = fname { assert_eq!("it_details_item_dir", fname); fields += 1; } } if let Some(path) = item.get(&DirEntryAttr::Path) { if let &DirEntryValue::String(ref path) = path { if !path.is_empty() { fields += 1; } } } if let Some(path) = item.get(&DirEntryAttr::DosPath) { if let &DirEntryValue::String(ref path) = path { if !path.is_empty() { fields += 1; } } } if let Some(size) = item.get(&DirEntryAttr::Size) { if let &DirEntryValue::U64(size) = size { assert_eq!(0, size); fields += 1; } } if let Some(is_dir) = item.get(&DirEntryAttr::IsDir) { if let &DirEntryValue::Boolean(is_dir) = is_dir { assert_eq!(true, is_dir); fields += 1; } } if let Some(is_file) = item.get(&DirEntryAttr::IsFile) { if let &DirEntryValue::Boolean(is_file) = is_file { assert_eq!(false, is_file); fields += 1; } } if let Some(modified) = item.get(&DirEntryAttr::Modified) { if let &DirEntryValue::SystemTime(modified) = modified { if modified.elapsed().unwrap().as_secs() == 0 { fields += 1; } } } if let Some(accessed) = item.get(&DirEntryAttr::Accessed) { if let &DirEntryValue::SystemTime(accessed) = accessed { if accessed.elapsed().unwrap().as_secs() == 0 { fields += 1; } } } assert_eq!(10, fields); } #[test] fn it_details_file_item() { let test_dir = Path::new(TEST_FOLDER).join("it_details_file_item"); create_all(&test_dir, true).unwrap(); let file = test_dir.join("file.txt"); fs_extra::file::write_all(&file, "content").unwrap(); assert!(file.exists()); let mut config = HashSet::new(); config.insert(DirEntryAttr::Name); config.insert(DirEntryAttr::Ext); config.insert(DirEntryAttr::FullName); config.insert(DirEntryAttr::Path); config.insert(DirEntryAttr::DosPath); config.insert(DirEntryAttr::Size); config.insert(DirEntryAttr::FileSize); config.insert(DirEntryAttr::IsDir); config.insert(DirEntryAttr::IsFile); config.insert(DirEntryAttr::Modified); config.insert(DirEntryAttr::Accessed); let item = get_details_entry(file, &config).unwrap(); assert_eq!(11, item.len()); let mut fields = 0; if let Some(name) = item.get(&DirEntryAttr::Name) { if let &DirEntryValue::String(ref name) = name { assert_eq!("file", name); fields += 1; } } if let Some(ext) = item.get(&DirEntryAttr::Ext) { if let &DirEntryValue::String(ref ext) = ext { assert_eq!("txt", ext); fields += 1; } } if let Some(fname) = item.get(&DirEntryAttr::FullName) { if let &DirEntryValue::String(ref fname) = fname { assert_eq!("file.txt", fname); fields += 1; } } if let Some(path) = item.get(&DirEntryAttr::Path) { if let &DirEntryValue::String(ref path) = path { if !path.is_empty() { fields += 1; } } } if let Some(path) = item.get(&DirEntryAttr::DosPath) { if let &DirEntryValue::String(ref path) = path { if !path.is_empty() { fields += 1; } } } if let Some(size) = item.get(&DirEntryAttr::Size) { if let &DirEntryValue::U64(size) = size { assert_eq!(7, size); fields += 1; } } if let Some(size) = item.get(&DirEntryAttr::FileSize) { if let &DirEntryValue::U64(size) = size { assert_eq!(7, size); fields += 1; } } if let Some(is_dir) = item.get(&DirEntryAttr::IsDir) { if let &DirEntryValue::Boolean(is_dir) = is_dir { assert_eq!(false, is_dir); fields += 1; } } if let Some(is_file) = item.get(&DirEntryAttr::IsFile) { if let &DirEntryValue::Boolean(is_file) = is_file { assert_eq!(true, is_file); fields += 1; } } if let Some(modified) = item.get(&DirEntryAttr::Modified) { if let &DirEntryValue::SystemTime(modified) = modified { if modified.elapsed().unwrap().as_secs() == 0 { fields += 1; } } } if let Some(accessed) = item.get(&DirEntryAttr::Accessed) { if let &DirEntryValue::SystemTime(accessed) = accessed { if accessed.elapsed().unwrap().as_secs() == 0 { fields += 1; } } } assert_eq!(11, fields); } #[test] fn it_details_item_dir_short() { let test_dir = Path::new(TEST_FOLDER).join("it_details_item_dir_short"); create_all(&test_dir, true).unwrap(); assert!(test_dir.exists()); let mut config = HashSet::new(); config.insert(DirEntryAttr::Name); config.insert(DirEntryAttr::Size); let item = get_details_entry(test_dir, &config).unwrap(); assert_eq!(2, item.len()); if let Some(name) = item.get(&DirEntryAttr::Name) { if let &DirEntryValue::String(ref name) = name { assert_eq!("it_details_item_dir_short", name); } } if let Some(size) = item.get(&DirEntryAttr::Size) { if let &DirEntryValue::U64(size) = size { assert_eq!(0, size); } } } #[test] fn it_details_item_file_short() { let test_dir = Path::new(TEST_FOLDER).join("it_details_item_short"); create_all(&test_dir, true).unwrap(); let file = test_dir.join("file.txt"); fs_extra::file::write_all(&file, "content").unwrap(); assert!(file.exists()); let mut config = HashSet::new(); config.insert(DirEntryAttr::Name); config.insert(DirEntryAttr::Size); let item = get_details_entry(file, &config).unwrap(); assert_eq!(2, item.len()); if let Some(name) = item.get(&DirEntryAttr::Name) { if let &DirEntryValue::String(ref name) = name { assert_eq!("file", name); } } if let Some(size) = item.get(&DirEntryAttr::Size) { if let &DirEntryValue::U64(size) = size { assert_eq!(7, size); } } } #[test] fn it_ls() { let test_dir = Path::new(TEST_FOLDER).join("it_ls"); create_all(&test_dir, true).unwrap(); let file1 = test_dir.join("file1.txt"); let file2 = test_dir.join("file2.txt"); fs_extra::file::write_all(&file1, "content").unwrap(); fs_extra::file::write_all(&file2, "content").unwrap(); assert!(file1.exists()); assert!(file2.exists()); let mut config = HashSet::new(); config.insert(DirEntryAttr::Name); config.insert(DirEntryAttr::Size); config.insert(DirEntryAttr::IsDir); config.insert(DirEntryAttr::BaseInfo); let ls_result = ls(&test_dir, &config).unwrap(); assert_eq!(2, ls_result.items.len()); assert_eq!(3, ls_result.base.len()); if let Some(name) = ls_result.base.get(&DirEntryAttr::Name) { if let &DirEntryValue::String(ref name) = name { assert_eq!("it_ls", name); } } if let Some(size) = ls_result.base.get(&DirEntryAttr::Size) { if let &DirEntryValue::U64(size) = size { assert_eq!(14, size); } } if let Some(is_dir) = ls_result.base.get(&DirEntryAttr::IsDir) { if let &DirEntryValue::Boolean(is_dir) = is_dir { assert_eq!(true, is_dir); } } for item in ls_result.items { if let Some(name) = item.get(&DirEntryAttr::Name) { if let &DirEntryValue::String(ref name) = name { assert_eq!(String::from("file"), name[..4]); } } if let Some(size) = item.get(&DirEntryAttr::Size) { if let &DirEntryValue::U64(size) = size { assert_eq!(7, size); } } if let Some(is_dir) = item.get(&DirEntryAttr::IsDir) { if let &DirEntryValue::Boolean(is_dir) = is_dir { assert_eq!(false, is_dir); } } } } #[test] fn it_copy_with_progress_exist_user_decide_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_user_decide_overwrite"); let out = test_dir.join("out"); let dir = (test_dir.join("dir"), out.join("dir")); let file1 = (dir.0.join("file1.txt"), dir.1.join("file1.txt")); let file2 = (dir.0.join("file2.txt"), dir.1.join("file2.txt")); create_all(&dir.0, true).unwrap(); create_all(&dir.1, true).unwrap(); assert!(&dir.0.exists()); assert!(&dir.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file1.1, "old content7").unwrap(); fs_extra::file::write_all(&file2.1, "old content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); let mut options = CopyOptions::new(); assert!(!compare_dir(&dir.0, &out)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let result: u64; { let func_test = |process_info: TransitProcess| { let result: TransitProcessResult; match process_info.state { TransitState::Exists => { count_exist_files += 1; result = TransitProcessResult::Overwrite; tx.send(process_info).unwrap(); } _ => result = TransitProcessResult::Abort, }; result }; result = copy_with_progress(&dir.0, &out, &options, func_test).unwrap(); } assert_eq!(2, count_exist_files); assert_eq!(16, result); assert!(dir.0.exists()); assert!(dir.1.exists()); assert!(compare_dir(&dir.0, &out)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_copy_with_progress_exist_user_decide_overwrite_all() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_user_decide_overwrite_all"); let out = test_dir.join("out"); let dir = (test_dir.join("dir"), out.join("dir")); let file1 = (dir.0.join("file1.txt"), dir.1.join("file1.txt")); let file2 = (dir.0.join("file2.txt"), dir.1.join("file2.txt")); create_all(&dir.0, true).unwrap(); create_all(&dir.1, true).unwrap(); assert!(&dir.0.exists()); assert!(&dir.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file1.1, "old content7").unwrap(); fs_extra::file::write_all(&file2.1, "old content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); let mut options = CopyOptions::new(); assert!(!compare_dir(&dir.0, &out)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let result: u64; { let func_test = |process_info: TransitProcess| { let result: TransitProcessResult; match process_info.state { TransitState::Exists => { count_exist_files += 1; result = TransitProcessResult::OverwriteAll; tx.send(process_info).unwrap(); } _ => result = TransitProcessResult::Abort, }; result }; result = copy_with_progress(&dir.0, &out, &options, func_test).unwrap(); } assert_eq!(1, count_exist_files); assert_eq!(16, result); assert!(dir.0.exists()); assert!(dir.1.exists()); assert!(compare_dir(&dir.0, &out)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_copy_with_progress_exist_user_decide_skip() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_user_decide_skip"); let out = test_dir.join("out"); let dir = (test_dir.join("dir"), out.join("dir")); let file1 = (dir.0.join("file1.txt"), dir.1.join("file1.txt")); let file2 = (dir.0.join("file2.txt"), dir.1.join("file2.txt")); create_all(&dir.0, true).unwrap(); create_all(&dir.1, true).unwrap(); assert!(&dir.0.exists()); assert!(&dir.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file1.1, "old content7").unwrap(); fs_extra::file::write_all(&file2.1, "old content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); let mut options = CopyOptions::new(); assert!(!compare_dir(&dir.0, &out)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let result: u64; { let func_test = |process_info: TransitProcess| { let result: TransitProcessResult; match process_info.state { TransitState::Exists => { count_exist_files += 1; result = TransitProcessResult::Skip; tx.send(process_info).unwrap(); } _ => result = TransitProcessResult::Abort, }; result }; result = copy_with_progress(&dir.0, &out, &options, func_test).unwrap(); } assert_eq!(2, count_exist_files); assert_eq!(0, result); assert!(dir.0.exists()); assert!(dir.1.exists()); assert!(!compare_dir(&dir.0, &out)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_copy_with_progress_exist_user_decide_skip_all() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_user_decide_skip_all"); let out = test_dir.join("out"); let dir = (test_dir.join("dir"), out.join("dir")); let file1 = (dir.0.join("file1.txt"), dir.1.join("file1.txt")); let file2 = (dir.0.join("file2.txt"), dir.1.join("file2.txt")); create_all(&dir.0, true).unwrap(); create_all(&dir.1, true).unwrap(); assert!(&dir.0.exists()); assert!(&dir.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file1.1, "old content7").unwrap(); fs_extra::file::write_all(&file2.1, "old content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); let mut options = CopyOptions::new(); assert!(!compare_dir(&dir.0, &out)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let result: u64; { let func_test = |process_info: TransitProcess| { let result: TransitProcessResult; match process_info.state { TransitState::Exists => { count_exist_files += 1; result = TransitProcessResult::SkipAll; tx.send(process_info).unwrap(); } _ => result = TransitProcessResult::Abort, }; result }; result = copy_with_progress(&dir.0, &out, &options, func_test).unwrap(); } assert_eq!(1, count_exist_files); assert_eq!(0, result); assert!(dir.0.exists()); assert!(dir.1.exists()); assert!(!compare_dir(&dir.0, &out)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_copy_with_progress_exist_user_decide_retry() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_user_decide_retry"); let out = test_dir.join("out"); let dir = (test_dir.join("dir"), out.join("dir")); let file1 = (dir.0.join("file1.txt"), dir.1.join("file1.txt")); let file2 = (dir.0.join("file2.txt"), dir.1.join("file2.txt")); create_all(&dir.0, true).unwrap(); create_all(&dir.1, true).unwrap(); assert!(&dir.0.exists()); assert!(&dir.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file1.1, "old content7").unwrap(); fs_extra::file::write_all(&file2.1, "old content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); let mut options = CopyOptions::new(); assert!(!compare_dir(&dir.0, &out)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let result: u64; { let func_test = |process_info: TransitProcess| { let result: TransitProcessResult; match process_info.state { TransitState::Exists => { if count_exist_files == 3 || count_exist_files == 6 { result = TransitProcessResult::Skip; } else { result = TransitProcessResult::Retry; } count_exist_files += 1; tx.send(process_info).unwrap(); } _ => result = TransitProcessResult::Abort, }; result }; result = copy_with_progress(&dir.0, &out, &options, func_test).unwrap(); } assert_eq!(7, count_exist_files); assert_eq!(0, result); assert!(dir.0.exists()); assert!(dir.1.exists()); assert!(!compare_dir(&dir.0, &out)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_copy_with_progress_inside_work_target_dir_not_exist() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join("it_copy_with_progress_inside_work_target_dir_not_exist"); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); create_all(&root_dir1_sub, true).unwrap(); fs_extra::file::write_all(&file1, "content").unwrap(); fs_extra::file::write_all(&file2, "content2").unwrap(); if root_dir2.exists() { remove(&root_dir2).unwrap(); } assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(!root_dir2.exists()); assert!(file1.exists()); assert!(file2.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&root_dir1, &root_dir2, &options, func_test).unwrap(); assert_eq!(15, result); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(compare_dir_recursively(&root_dir1, &root_dir2)); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "file2.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(15, process_info.total_bytes); } else if process_info.file_name == "file1.txt" { assert_eq!(7, process_info.file_total_bytes); assert_eq!(15, process_info.total_bytes); } else { panic!("Unknow file name!"); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_copy_with_progress_inside_work_target_dir_exist_with_no_source_dir_named_sub_dir() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join( "it_copy_with_progress_inside_work_target_dir_exist_with_no_source_dir_named_sub_dir", ); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let root_dir2_dir1 = root_dir2.join("dir1"); let root_dir2_dir3 = root_dir2.join("dir3"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); let file3 = root_dir2_dir3.join("file3.txt"); create_all(&root_dir1_sub, true).unwrap(); create_all(&root_dir2_dir3, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content22").unwrap(); fs_extra::file::write_all(&file3, "content333").unwrap(); if root_dir2_dir1.exists() { remove(&root_dir2_dir1).unwrap(); } assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(!root_dir2_dir1.exists()); assert!(root_dir2_dir3.exists()); assert!(file1.exists()); assert!(file2.exists()); assert!(file3.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&root_dir1, &root_dir2, &options, func_test).unwrap(); assert_eq!(17, result); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir3.exists()); assert!(compare_dir(&root_dir1, &root_dir2)); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "file2.txt" { assert_eq!(9, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else if process_info.file_name == "file1.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else { panic!("Unknow file name!"); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_copy_with_progress_inside_no_overwrite_work_target_dir_exist_with_source_dir_exist() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join( "it_copy_with_progress_inside_no_overwrite_work_target_dir_exist_with_source_dir_exist", ); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let root_dir2_dir1 = root_dir2.join("dir1"); let root_dir2_dir1_sub = root_dir2_dir1.join("sub"); let root_dir2_dir3 = root_dir2.join("dir3"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); let file3 = root_dir2_dir3.join("file3.txt"); let old_file1 = root_dir2_dir1.join("file1.txt"); let old_file2 = root_dir2_dir1_sub.join("file2.txt"); create_all(&root_dir1_sub, true).unwrap(); create_all(&root_dir2_dir3, true).unwrap(); create_all(&root_dir2_dir1, true).unwrap(); create_all(&root_dir2_dir1_sub, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content22").unwrap(); fs_extra::file::write_all(&file3, "content333").unwrap(); fs_extra::file::write_all(&old_file1, "old_content1").unwrap(); fs_extra::file::write_all(&old_file2, "old_content22").unwrap(); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); assert!(file1.exists()); assert!(file2.exists()); assert!(file3.exists()); assert!(old_file1.exists()); assert!(old_file2.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::Skip }; let result = copy_with_progress(&root_dir1, &root_dir2, &options, func_test).unwrap(); assert_eq!(0, result); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); assert!(!files_eq(file1, old_file1)); assert!(!files_eq(file2, old_file2)); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "file2.txt" { assert_eq!(9, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else if process_info.file_name == "file1.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else { panic!("Unknow file name!"); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_copy_with_progress_inside_overwrite_work_target_dir_exist_with_source_dir_exist() { let path_root = Path::new(TEST_FOLDER); let root = path_root .join("it_copy_with_progress_inside_overwrite_work_target_dir_exist_with_source_dir_exist"); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let root_dir2_dir1 = root_dir2.join("dir1"); let root_dir2_dir1_sub = root_dir2_dir1.join("sub"); let root_dir2_dir3 = root_dir2.join("dir3"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); let file3 = root_dir2_dir3.join("file3.txt"); let old_file1 = root_dir2_dir1.join("file1.txt"); let old_file2 = root_dir2_dir1_sub.join("file2.txt"); create_all(&root_dir1_sub, true).unwrap(); create_all(&root_dir2_dir3, true).unwrap(); create_all(&root_dir2_dir1, true).unwrap(); create_all(&root_dir2_dir1_sub, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content22").unwrap(); fs_extra::file::write_all(&file3, "content333").unwrap(); fs_extra::file::write_all(&old_file1, "old_content1").unwrap(); fs_extra::file::write_all(&old_file2, "old_content22").unwrap(); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); assert!(file1.exists()); assert!(file2.exists()); assert!(file3.exists()); assert!(old_file1.exists()); assert!(old_file2.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; options.overwrite = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = copy_with_progress(&root_dir1, &root_dir2, &options, func_test).unwrap(); assert_eq!(17, result); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); assert!(compare_dir(&root_dir1, &root_dir2)); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "file2.txt" { assert_eq!(9, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else if process_info.file_name == "file1.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else { panic!("Unknow file name!"); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_move_with_progress_exist_user_decide_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_user_decide_overwrite"); let out = test_dir.join("out"); let dir = (test_dir.join("dir"), out.join("dir")); let file1 = (dir.0.join("file1.txt"), dir.1.join("file1.txt")); let file2 = (dir.0.join("file2.txt"), dir.1.join("file2.txt")); create_all(&dir.0, true).unwrap(); create_all(&dir.1, true).unwrap(); assert!(&dir.0.exists()); assert!(&dir.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file1.1, "old content7").unwrap(); fs_extra::file::write_all(&file2.1, "old content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); let mut options = CopyOptions::new(); assert!(!compare_dir(&dir.0, &out)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let result: u64; { let func_test = |process_info: TransitProcess| { let result: TransitProcessResult; match process_info.state { TransitState::Exists => { count_exist_files += 1; result = TransitProcessResult::Overwrite; tx.send(process_info).unwrap(); } _ => result = TransitProcessResult::Abort, }; result }; result = move_dir_with_progress(&dir.0, &out, &options, func_test).unwrap(); } assert_eq!(2, count_exist_files); assert_eq!(16, result); assert!(!dir.0.exists()); assert!(dir.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_move_with_progress_exist_user_decide_overwrite_all() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_user_decide_overwrite_all"); let out = test_dir.join("out"); let dir = (test_dir.join("dir"), out.join("dir")); let file1 = (dir.0.join("file1.txt"), dir.1.join("file1.txt")); let file2 = (dir.0.join("file2.txt"), dir.1.join("file2.txt")); create_all(&dir.0, true).unwrap(); create_all(&dir.1, true).unwrap(); assert!(&dir.0.exists()); assert!(&dir.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file1.1, "old content7").unwrap(); fs_extra::file::write_all(&file2.1, "old content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); let mut options = CopyOptions::new(); assert!(!compare_dir(&dir.0, &out)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let result: u64; { let func_test = |process_info: TransitProcess| { let result: TransitProcessResult; match process_info.state { TransitState::Exists => { count_exist_files += 1; result = TransitProcessResult::OverwriteAll; tx.send(process_info).unwrap(); } _ => result = TransitProcessResult::Abort, }; result }; result = move_dir_with_progress(&dir.0, &out, &options, func_test).unwrap(); } assert_eq!(1, count_exist_files); assert_eq!(16, result); assert!(!dir.0.exists()); assert!(dir.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_move_with_progress_exist_user_decide_skip() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_user_decide_skip"); let out = test_dir.join("out"); let dir = (test_dir.join("dir"), out.join("dir")); let file1 = (dir.0.join("file1.txt"), dir.1.join("file1.txt")); let file2 = (dir.0.join("file2.txt"), dir.1.join("file2.txt")); create_all(&dir.0, true).unwrap(); create_all(&dir.1, true).unwrap(); assert!(&dir.0.exists()); assert!(&dir.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file1.1, "old content7").unwrap(); fs_extra::file::write_all(&file2.1, "old content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); let mut options = CopyOptions::new(); assert!(!compare_dir(&dir.0, &out)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let result: u64; { let func_test = |process_info: TransitProcess| { let result: TransitProcessResult; match process_info.state { TransitState::Exists => { count_exist_files += 1; result = TransitProcessResult::Skip; tx.send(process_info).unwrap(); } _ => result = TransitProcessResult::Abort, }; result }; result = move_dir_with_progress(&dir.0, &out, &options, func_test).unwrap(); } assert_eq!(2, count_exist_files); assert_eq!(0, result); assert!(dir.0.exists()); assert!(dir.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_move_with_progress_exist_user_decide_skip_all() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_user_decide_skip_all"); let out = test_dir.join("out"); let dir = (test_dir.join("dir"), out.join("dir")); let file1 = (dir.0.join("file1.txt"), dir.1.join("file1.txt")); let file2 = (dir.0.join("file2.txt"), dir.1.join("file2.txt")); create_all(&dir.0, true).unwrap(); create_all(&dir.1, true).unwrap(); assert!(&dir.0.exists()); assert!(&dir.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file1.1, "old content7").unwrap(); fs_extra::file::write_all(&file2.1, "old content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); let mut options = CopyOptions::new(); assert!(!compare_dir(&dir.0, &out)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let result: u64; { let func_test = |process_info: TransitProcess| { let result: TransitProcessResult; match process_info.state { TransitState::Exists => { count_exist_files += 1; result = TransitProcessResult::SkipAll; tx.send(process_info).unwrap(); } _ => result = TransitProcessResult::Abort, }; result }; result = move_dir_with_progress(&dir.0, &out, &options, func_test).unwrap(); } assert_eq!(1, count_exist_files); assert_eq!(0, result); assert!(dir.0.exists()); assert!(dir.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_move_with_progress_exist_user_decide_retry() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_user_decide_retry"); let out = test_dir.join("out"); let dir = (test_dir.join("dir"), out.join("dir")); let file1 = (dir.0.join("file1.txt"), dir.1.join("file1.txt")); let file2 = (dir.0.join("file2.txt"), dir.1.join("file2.txt")); create_all(&dir.0, true).unwrap(); create_all(&dir.1, true).unwrap(); assert!(&dir.0.exists()); assert!(&dir.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file1.1, "old content7").unwrap(); fs_extra::file::write_all(&file2.1, "old content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); let mut options = CopyOptions::new(); assert!(!compare_dir(&dir.0, &out)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let result: u64; { let func_test = |process_info: TransitProcess| { let result: TransitProcessResult; match process_info.state { TransitState::Exists => { if count_exist_files == 3 || count_exist_files == 6 { result = TransitProcessResult::Skip; } else { result = TransitProcessResult::Retry; } count_exist_files += 1; tx.send(process_info).unwrap(); } _ => result = TransitProcessResult::Abort, }; result }; result = move_dir_with_progress(&dir.0, &out, &options, func_test).unwrap(); } assert_eq!(7, count_exist_files); assert_eq!(0, result); assert!(dir.0.exists()); assert!(dir.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_move_dir_with_progress_inside_work_target_dir_not_exist() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join("it_move_dir_with_progress_inside_work_target_dir_not_exist"); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); create_all(&root_dir1_sub, true).unwrap(); fs_extra::file::write_all(&file1, "content").unwrap(); fs_extra::file::write_all(&file2, "content2").unwrap(); if root_dir2.exists() { remove(&root_dir2).unwrap(); } assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(!root_dir2.exists()); assert!(file1.exists()); assert!(file2.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = move_dir_with_progress(&root_dir1, &root_dir2, &options, func_test).unwrap(); assert_eq!(15, result); assert!(!root_dir1.exists()); let root_dir2_sub = root_dir2.join("sub"); let root_dir2_file1 = root_dir2.join("file1.txt"); let root_dir2_sub_file2 = root_dir2_sub.join("file2.txt"); assert!(root_dir2.exists()); assert!(root_dir2_sub.exists()); assert!(root_dir2_file1.exists()); assert!(root_dir2_sub_file2.exists()); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "file2.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(15, process_info.total_bytes); } else if process_info.file_name == "file1.txt" { assert_eq!(7, process_info.file_total_bytes); assert_eq!(15, process_info.total_bytes); } else { panic!("Unknow file name!"); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_move_dir_with_progress_inside_work_target_dir_exist_with_no_source_dir_named_sub_dir() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join( "it_move_dir_with_progress_inside_work_target_dir_exist_with_no_source_dir_named_sub_dir", ); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let root_dir2_dir1 = root_dir2.join("dir1"); let root_dir2_dir3 = root_dir2.join("dir3"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); let file3 = root_dir2_dir3.join("file3.txt"); create_all(&root_dir1_sub, true).unwrap(); create_all(&root_dir2_dir3, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content22").unwrap(); fs_extra::file::write_all(&file3, "content333").unwrap(); if root_dir2_dir1.exists() { remove(&root_dir2_dir1).unwrap(); } assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(!root_dir2_dir1.exists()); assert!(root_dir2_dir3.exists()); assert!(file1.exists()); assert!(file2.exists()); assert!(file3.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = move_dir_with_progress(&root_dir1, &root_dir2, &options, func_test).unwrap(); assert_eq!(17, result); assert!(!root_dir1.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir3.exists()); let root_dir2_dir1_file1 = root_dir2_dir1.join("file1.txt"); let root_dir2_dir1_sub = root_dir2_dir1.join("sub"); let root_dir2_dir1_sub_file2 = root_dir2_dir1_sub.join("file2.txt"); let root_dir2_dir3_file3 = root_dir2_dir3.join("file3.txt"); assert!(root_dir2_dir1_file1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir1_sub_file2.exists()); assert!(root_dir2_dir3_file3.exists()); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "file2.txt" { assert_eq!(9, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else if process_info.file_name == "file1.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else { panic!("Unknow file name!"); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_move_dir_with_progress_inside_no_overwrite_work_target_dir_exist_with_source_dir_exist() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join( "it_move_dir_with_progress_inside_no_overwrite_work_target_dir_exist_with_source_dir_exist", ); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let root_dir2_dir1 = root_dir2.join("dir1"); let root_dir2_dir1_sub = root_dir2_dir1.join("sub"); let root_dir2_dir3 = root_dir2.join("dir3"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); let file3 = root_dir2_dir3.join("file3.txt"); let old_file1 = root_dir2_dir1.join("file1.txt"); let old_file2 = root_dir2_dir1_sub.join("file2.txt"); create_all(&root_dir1_sub, true).unwrap(); create_all(&root_dir2_dir3, true).unwrap(); create_all(&root_dir2_dir1, true).unwrap(); create_all(&root_dir2_dir1_sub, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content22").unwrap(); fs_extra::file::write_all(&file3, "content333").unwrap(); fs_extra::file::write_all(&old_file1, "old_content1").unwrap(); fs_extra::file::write_all(&old_file2, "old_content22").unwrap(); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); assert!(file1.exists()); assert!(file2.exists()); assert!(file3.exists()); assert!(old_file1.exists()); assert!(old_file2.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::Skip }; let result = move_dir_with_progress(&root_dir1, &root_dir2, &options, func_test).unwrap(); assert_eq!(0, result); assert!(root_dir1.exists()); assert!(file1.exists()); assert!(root_dir1_sub.exists()); assert!(file2.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); let root_dir2_dir1_file1 = root_dir2_dir1.join("file1.txt"); let root_dir2_dir1_sub_file2 = root_dir2_dir1_sub.join("file2.txt"); let root_dir2_dir3_file3 = root_dir2_dir3.join("file3.txt"); assert!(root_dir2_dir1_file1.exists()); assert!(root_dir2_dir1_sub_file2.exists()); assert!(root_dir2_dir3_file3.exists()); assert!(!files_eq(file1, old_file1)); assert!(!files_eq(file2, old_file2)); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "file2.txt" { assert_eq!(9, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else if process_info.file_name == "file1.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else { panic!("Unknow file name!"); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_move_dir_with_progress_inside_overwrite_work_target_dir_exist_with_source_dir_exist() { let path_root = Path::new(TEST_FOLDER); let root = path_root.join( "it_move_dir_with_progress_inside_overwrite_work_target_dir_exist_with_source_dir_exist", ); let root_dir1 = root.join("dir1"); let root_dir1_sub = root_dir1.join("sub"); let root_dir2 = root.join("dir2"); let root_dir2_dir1 = root_dir2.join("dir1"); let root_dir2_dir1_sub = root_dir2_dir1.join("sub"); let root_dir2_dir3 = root_dir2.join("dir3"); let file1 = root_dir1.join("file1.txt"); let file2 = root_dir1_sub.join("file2.txt"); let file3 = root_dir2_dir3.join("file3.txt"); let old_file1 = root_dir2_dir1.join("file1.txt"); let old_file2 = root_dir2_dir1_sub.join("file2.txt"); create_all(&root_dir1_sub, true).unwrap(); create_all(&root_dir2_dir3, true).unwrap(); create_all(&root_dir2_dir1, true).unwrap(); create_all(&root_dir2_dir1_sub, true).unwrap(); fs_extra::file::write_all(&file1, "content1").unwrap(); fs_extra::file::write_all(&file2, "content22").unwrap(); fs_extra::file::write_all(&file3, "content333").unwrap(); fs_extra::file::write_all(&old_file1, "old_content1").unwrap(); fs_extra::file::write_all(&old_file2, "old_content22").unwrap(); assert!(root_dir1.exists()); assert!(root_dir1_sub.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); assert!(file1.exists()); assert!(file2.exists()); assert!(file3.exists()); assert!(old_file1.exists()); assert!(old_file2.exists()); let mut options = CopyOptions::new(); options.copy_inside = true; options.overwrite = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = move_dir_with_progress(&root_dir1, &root_dir2, &options, func_test).unwrap(); assert_eq!(17, result); assert!(!root_dir1.exists()); assert!(root_dir2.exists()); assert!(root_dir2_dir1.exists()); assert!(root_dir2_dir1_sub.exists()); assert!(root_dir2_dir3.exists()); let root_dir2_dir1_file1 = root_dir2_dir1.join("file1.txt"); let root_dir2_dir1_sub_file2 = root_dir2_dir1_sub.join("file2.txt"); let root_dir2_dir3_file3 = root_dir2_dir3.join("file3.txt"); assert!(root_dir2_dir1_file1.exists()); assert!(root_dir2_dir1_sub_file2.exists()); assert!(root_dir2_dir3_file3.exists()); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "file2.txt" { assert_eq!(9, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else if process_info.file_name == "file1.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(17, process_info.total_bytes); } else { panic!("Unknow file name!"); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_move_with_progress_content_only_option() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_content_only_option"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.clone()); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); create_all(&d_level_1.0, true).unwrap(); create_all(&d_level_2.0, true).unwrap(); create_all(&d_level_3.0, true).unwrap(); create_all(&path_to, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); let mut options = CopyOptions::new(); options.content_only = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); TransitProcessResult::ContinueOrAbort }; let result = move_dir_with_progress(&d_level_1.0, &path_to, &options, func_test).unwrap(); assert_eq!(24, result); assert!(!d_level_1.0.exists()); assert!(!d_level_2.0.exists()); assert!(!d_level_3.0.exists()); assert!(d_level_1.1.exists()); assert!(d_level_2.1.exists()); assert!(d_level_3.1.exists()); assert!(!file1.0.exists()); assert!(!file2.0.exists()); assert!(!file3.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } fs_extra-1.2.0/tests/file.rs010064400017500001731000001120021360570752700142040ustar0000000000000000// use std::io::{ErrorKind, Result}; use std::path::{Path, PathBuf}; use std::thread; use std::sync::mpsc; extern crate fs_extra; use fs_extra::file::*; use fs_extra::error::*; const TEST_FOLDER: &'static str = "./tests/temp/file"; fn files_eq(file1: P, file2: Q) -> Result where P: AsRef, Q: AsRef, { let content1 = read_to_string(file1)?; let content2 = read_to_string(file2)?; Ok(content1 == content2) } #[test] fn it_read_and_write_work() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_read_and_write_work"); test_file.push("test.txt"); fs_extra::dir::create_all(test_file.parent().unwrap(), true).unwrap(); let content1 = "test_1"; let content2 = "test_2"; write_all(&test_file, &content1).unwrap(); assert!(test_file.exists()); let read1 = read_to_string(&test_file).unwrap(); assert_eq!(content1, read1); write_all(&test_file, &content2).unwrap(); let read2 = read_to_string(&test_file).unwrap(); assert_eq!(content2, read2); } #[test] fn it_read_not_exist_file() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_read_not_exist_file"); test_file.push("test.txt"); fs_extra::dir::create_all(test_file.parent().unwrap(), true).unwrap(); assert!(!test_file.exists()); match read_to_string(&test_file) { Ok(_) => panic!("should be error"), Err(err) => match err.kind { ErrorKind::NotFound => {} _ => panic!("wrong error"), }, } } #[test] fn it_read_not_file() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_read_not_file"); fs_extra::dir::create_all(&test_file, true).unwrap(); match read_to_string(&test_file) { Ok(_) => panic!("should be error"), Err(err) => match err.kind { ErrorKind::InvalidFile => {} _ => panic!("wrong error"), }, } } #[test] fn it_write_not_file() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_write_not_file"); test_file.push("test.txt"); fs_extra::dir::create_all(test_file.parent().unwrap(), true).unwrap(); assert!(!test_file.exists()); test_file.pop(); match write_all(test_file, "content") { Ok(_) => panic!("should be error"), Err(err) => match err.kind { ErrorKind::InvalidFile => {} _ => panic!("wrong error"), }, } } #[test] fn it_remove_file() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_remove_file"); test_file.push("test.txt"); fs_extra::dir::create_all(test_file.parent().unwrap(), true).unwrap(); write_all(&test_file, "test").unwrap(); assert!(test_file.exists()); remove(&test_file).unwrap(); assert!(!test_file.exists()); } #[test] fn it_copy_work() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_work"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); assert!(test_file.exists()); assert!(!test_file_out.exists()); let options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); assert!(test_file_out.exists()); assert_eq!(test_file.file_name(), test_file_out.file_name()); assert!(files_eq(test_file, test_file_out).unwrap()); } #[test] fn it_copy_not_file() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_work"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); assert!(test_file.exists()); assert!(!test_file_out.exists()); test_file.pop(); let options = CopyOptions::new(); match copy(&test_file, &test_file_out, &options) { Err(err) => match err.kind { ErrorKind::InvalidFile => { let wrong_path = format!("Path \"{}\" is not a file!", test_file.to_str().unwrap()); assert_eq!(wrong_path, err.to_string()); } _ => { panic!("wrong error"); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_copy_source_not_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_source_not_exist"); let mut test_file_out = test_file.clone(); test_file.push("test1.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); assert!(!test_file.exists()); let options = CopyOptions::new(); match copy(&test_file, test_file_out, &options) { Ok(_) => panic!("should be error"), Err(err) => match err.kind { ErrorKind::NotFound => { let wrong_path = format!( "Path \"{}\" does not exist or you don't have \ access!", test_file.to_str().unwrap() ); assert_eq!(wrong_path, err.to_string()); () } _ => panic!("wrong error"), }, } } #[test] fn it_copy_exist_overwrite() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_exist_overwrite"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); assert!(files_eq(&test_file, &test_file_out).unwrap()); options.overwrite = true; write_all(&test_file, "test_data2").unwrap(); match copy(&test_file, &test_file_out, &options) { Ok(_) => { assert!(test_file.exists()); assert_eq!(read_to_string(test_file_out).unwrap(), "test_data2"); () } Err(err) => panic!(err.to_string()), } } #[test] fn it_copy_exist_not_overwrite() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_exist_not_overwrite"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); options.overwrite = false; write_all(&test_file, "test_data2").unwrap(); match copy(&test_file, &test_file_out, &options) { Ok(_) => panic!("should be error"), Err(err) => { let file_path = format!("Path \"{}\" is exist", test_file_out.to_str().unwrap()); assert_eq!(file_path, err.to_string()); assert!(!files_eq(test_file, test_file_out).unwrap()); () } } } #[test] fn it_copy_exist_skip_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_exist_skip_exist"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); options.skip_exist = true; write_all(&test_file, "test_data2").unwrap(); match copy(&test_file, &test_file_out, &options) { Ok(_) => { assert!(!files_eq(test_file, test_file_out).unwrap()); () } Err(_) => panic!("should be error"), } } #[test] fn it_copy_exist_overwrite_and_skip_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_exist_overwrite_and_skip_exist"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); assert!(files_eq(&test_file, &test_file_out).unwrap()); options.overwrite = true; options.skip_exist = true; write_all(&test_file, "test_data2").unwrap(); match copy(&test_file, &test_file_out, &options) { Ok(_) => { assert!(test_file.exists()); assert_eq!(read_to_string(test_file_out).unwrap(), "test_data2"); () } Err(err) => panic!(err.to_string()), } } #[test] fn it_copy_with_progress_work() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_with_progress_work"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); assert!(test_file.exists()); assert!(!test_file_out.exists()); let mut options = CopyOptions::new(); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); }; copy_with_progress(&test_file, &test_file_out, &options, func_test).unwrap(); assert!(test_file.exists()); assert!(test_file_out.exists()); assert_eq!(test_file.file_name(), test_file_out.file_name()); assert!(files_eq(test_file, test_file_out).unwrap()); }); for i in 1..10 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i, process_info.copied_bytes); assert_eq!(9, process_info.total_bytes); } } #[test] fn it_copy_progress_not_file() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_progress_not_file"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); assert!(test_file.exists()); assert!(!test_file_out.exists()); test_file.pop(); let options = CopyOptions::new(); let func_test = |process_info: TransitProcess| println!("{}", process_info.total_bytes); match copy_with_progress(&test_file, &test_file_out, &options, func_test) { Err(err) => match err.kind { ErrorKind::InvalidFile => { let wrong_path = format!("Path \"{}\" is not a file!", test_file.to_str().unwrap()); assert_eq!(wrong_path, err.to_string()); } _ => { panic!("wrong error"); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_copy_with_progress_work_dif_buf_size() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_with_progress_work_dif_buf_size"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data_").unwrap(); assert!(test_file.exists()); assert!(!test_file_out.exists()); let mut options = CopyOptions::new(); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); }; copy_with_progress(&test_file, &test_file_out, &options, func_test).unwrap(); assert!(test_file.exists()); assert!(test_file_out.exists()); assert_eq!(test_file.file_name(), test_file_out.file_name()); assert!(files_eq(&test_file, &test_file_out).unwrap()); let mut options = CopyOptions::new(); options.buffer_size = 2; options.overwrite = true; let (tx, rx) = mpsc::channel(); thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); }; copy_with_progress(&test_file, &test_file_out, &options, func_test).unwrap(); }); for i in 1..6 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i * 2, process_info.copied_bytes); assert_eq!(10, process_info.total_bytes); } }); for i in 1..11 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i, process_info.copied_bytes); assert_eq!(10, process_info.total_bytes); } } #[test] fn it_copy_with_progress_source_not_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_with_progress_source_not_exist"); let mut test_file_out = test_file.clone(); test_file.push("test1.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); assert!(!test_file.exists()); let options = CopyOptions::new(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); }; match copy_with_progress(&test_file, &test_file_out, &options, func_test) { Ok(_) => panic!("should be error"), Err(err) => match err.kind { ErrorKind::NotFound => { let wrong_path = format!( "Path \"{}\" does not exist or you don't have \ access!", test_file.to_str().unwrap() ); assert_eq!(wrong_path, err.to_string()); () } _ => panic!("wrong error"), }, } } #[test] fn it_copy_with_progress_exist_overwrite() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_with_progress_exist_overwrite"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); assert!(files_eq(&test_file, &test_file_out).unwrap()); options.overwrite = true; write_all(&test_file, "test_data2").unwrap(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); }; match copy_with_progress(&test_file, &test_file_out, &options, func_test) { Ok(_) => { assert!(test_file.exists()); assert_eq!(read_to_string(test_file_out).unwrap(), "test_data2"); () } Err(err) => panic!(err.to_string()), } } #[test] fn it_copy_with_progress_exist_not_overwrite() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_with_progress_exist_not_overwrite"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); options.overwrite = false; write_all(&test_file, "test_data2").unwrap(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); }; match copy_with_progress(&test_file, &test_file_out, &options, func_test) { Ok(_) => panic!("should be error"), Err(err) => { let file_path = format!("Path \"{}\" is exist", test_file_out.to_str().unwrap()); assert_eq!(file_path, err.to_string()); assert!(!files_eq(test_file, test_file_out).unwrap()); () } } } #[test] fn it_copy_with_progress_exist_skip_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_with_progress_exist_skip_exist"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); options.skip_exist = true; write_all(&test_file, "test_data2").unwrap(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); }; match copy_with_progress(&test_file, &test_file_out, &options, func_test) { Ok(_) => { assert!(!files_eq(test_file, test_file_out).unwrap()); () } Err(_) => panic!("should be error"), } } #[test] fn it_copy_with_progress_exist_overwrite_and_skip_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_copy_with_progress_exist_overwrite_and_skip_exist"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); assert!(files_eq(&test_file, &test_file_out).unwrap()); options.overwrite = true; options.skip_exist = true; write_all(&test_file, "test_data2").unwrap(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); }; match copy_with_progress(&test_file, &test_file_out, &options, func_test) { Ok(_) => { assert!(test_file.exists()); assert_eq!(read_to_string(test_file_out).unwrap(), "test_data2"); () } Err(err) => panic!(err.to_string()), } } #[test] fn it_move_work() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_work"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); assert!(test_file.exists()); assert!(!test_file_out.exists()); let options = CopyOptions::new(); let old_name = test_file.file_name(); let old_content = read_to_string(&test_file).unwrap(); move_file(&test_file, &test_file_out, &options).unwrap(); assert!(!test_file.exists()); assert!(test_file_out.exists()); assert_eq!(old_name, test_file_out.file_name()); let new_content = read_to_string(&test_file_out).unwrap(); assert_eq!(old_content, new_content); } #[test] fn it_move_not_file() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_work"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); assert!(test_file.exists()); assert!(!test_file_out.exists()); test_file.pop(); let options = CopyOptions::new(); match move_file(&test_file, &test_file_out, &options) { Err(err) => match err.kind { ErrorKind::InvalidFile => { let wrong_path = format!("Path \"{}\" is not a file!", test_file.to_str().unwrap()); assert_eq!(wrong_path, err.to_string()); } _ => { panic!("wrong error"); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_move_source_not_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_source_not_exist"); let mut test_file_out = test_file.clone(); test_file.push("test1.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); assert!(!test_file.exists()); let options = CopyOptions::new(); match move_file(&test_file, &test_file_out, &options) { Ok(_) => panic!("should be error"), Err(err) => match err.kind { ErrorKind::NotFound => { let wrong_path = format!( "Path \"{}\" does not exist or you don't have \ access!", test_file.to_str().unwrap() ); assert_eq!(wrong_path, err.to_string()); () } _ => panic!("wrong error"), }, } } #[test] fn it_move_exist_overwrite() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_exist_overwrite"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); assert!(files_eq(&test_file, &test_file_out).unwrap()); options.overwrite = true; write_all(&test_file, "test_data2").unwrap(); match move_file(&test_file, &test_file_out, &options) { Ok(_) => { assert!(!test_file.exists()); assert_eq!(read_to_string(test_file_out).unwrap(), "test_data2"); () } Err(err) => panic!(err.to_string()), } } #[test] fn it_move_exist_not_overwrite() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_exist_not_overwrite"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); options.overwrite = false; write_all(&test_file, "test_data2").unwrap(); match move_file(&test_file, &test_file_out, &options) { Ok(_) => panic!("should be error"), Err(err) => { let file_path = format!("Path \"{}\" is exist", test_file_out.to_str().unwrap()); assert_eq!(file_path, err.to_string()); assert!(!files_eq(test_file, test_file_out).unwrap()); () } } } #[test] fn it_move_exist_skip_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_exist_skip_exist"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); options.skip_exist = true; write_all(&test_file, "test_data2").unwrap(); match move_file(&test_file, &test_file_out, &options) { Ok(_) => { assert!(!files_eq(test_file, test_file_out).unwrap()); () } Err(_) => panic!("should be error"), } } #[test] fn it_move_exist_overwrite_and_skip_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_exist_overwrite_and_skip_exist"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); assert!(files_eq(&test_file, &test_file_out).unwrap()); options.overwrite = true; options.skip_exist = true; write_all(&test_file, "test_data2").unwrap(); match move_file(&test_file, &test_file_out, &options) { Ok(_) => { assert!(!test_file.exists()); assert_eq!(read_to_string(test_file_out).unwrap(), "test_data2"); () } Err(err) => panic!(err.to_string()), } } #[test] fn it_move_with_progress_work() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_with_progress_work"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); assert!(test_file.exists()); assert!(!test_file_out.exists()); let mut options = CopyOptions::new(); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); thread::spawn(move || { let old_name = test_file.file_name(); let old_content = read_to_string(&test_file).unwrap(); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); }; move_file_with_progress(&test_file, &test_file_out, &options, func_test).unwrap(); assert!(!test_file.exists()); assert!(test_file_out.exists()); assert_eq!(old_name, test_file_out.file_name()); let new_content = read_to_string(&test_file_out).unwrap(); assert_eq!(old_content, new_content); }); for i in 1..10 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i, process_info.copied_bytes); assert_eq!(9, process_info.total_bytes); } } #[test] fn it_move_progress_not_file() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_progress_not_file"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); assert!(test_file.exists()); assert!(!test_file_out.exists()); test_file.pop(); let options = CopyOptions::new(); let func_test = |process_info: TransitProcess| println!("{}", process_info.total_bytes); match move_file_with_progress(&test_file, &test_file_out, &options, func_test) { Err(err) => match err.kind { ErrorKind::InvalidFile => { let wrong_path = format!("Path \"{}\" is not a file!", test_file.to_str().unwrap()); assert_eq!(wrong_path, err.to_string()); } _ => { panic!("wrong error"); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_move_with_progress_work_dif_buf_size() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_with_progress_work_dif_buf_size"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data_").unwrap(); assert!(test_file.exists()); assert!(!test_file_out.exists()); let mut options = CopyOptions::new(); options.buffer_size = 2; let (tx, rx) = mpsc::channel(); thread::spawn(move || { let old_name = test_file.file_name(); let old_content = read_to_string(&test_file).unwrap(); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); }; move_file_with_progress(&test_file, &test_file_out, &options, func_test).unwrap(); assert!(!test_file.exists()); assert!(test_file_out.exists()); assert_eq!(old_name, test_file_out.file_name()); let new_content = read_to_string(&test_file_out).unwrap(); assert_eq!(old_content, new_content); }); for i in 1..6 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i * 2, process_info.copied_bytes); assert_eq!(10, process_info.total_bytes); } } #[test] fn it_move_with_progress_source_not_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_with_progress_source_not_exist"); let mut test_file_out = test_file.clone(); test_file.push("test1.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); assert!(!test_file.exists()); let options = CopyOptions::new(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); }; match move_file_with_progress(&test_file, &test_file_out, &options, func_test) { Ok(_) => panic!("should be error"), Err(err) => match err.kind { ErrorKind::NotFound => { let wrong_path = format!( "Path \"{}\" does not exist or you don't have \ access!", test_file.to_str().unwrap() ); assert_eq!(wrong_path, err.to_string()); () } _ => panic!("wrong error"), }, } } #[test] fn it_move_with_progress_exist_overwrite() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_with_progress_exist_overwrite"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); assert!(files_eq(&test_file, &test_file_out).unwrap()); options.overwrite = true; write_all(&test_file, "test_data2").unwrap(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); }; match move_file_with_progress(&test_file, &test_file_out, &options, func_test) { Ok(_) => { assert!(!test_file.exists()); assert_eq!(read_to_string(test_file_out).unwrap(), "test_data2"); () } Err(err) => panic!(err.to_string()), } } #[test] fn it_move_with_progress_exist_not_overwrite() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_with_progress_exist_not_overwrite"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); options.overwrite = false; write_all(&test_file, "test_data2").unwrap(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); }; match move_file_with_progress(&test_file, &test_file_out, &options, func_test) { Ok(_) => panic!("should be error"), Err(err) => { let file_path = format!("Path \"{}\" is exist", test_file_out.to_str().unwrap()); assert_eq!(file_path, err.to_string()); assert!(!files_eq(test_file, test_file_out).unwrap()); () } } } #[test] fn it_move_with_progress_exist_skip_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_with_progress_exist_skip_exist"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); options.skip_exist = true; write_all(&test_file, "test_data2").unwrap(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); }; match move_file_with_progress(&test_file, &test_file_out, &options, func_test) { Ok(_) => { assert!(!files_eq(test_file, test_file_out).unwrap()); () } Err(_) => panic!("should be error"), } } #[test] fn it_move_with_progress_exist_overwrite_and_skip_exist() { let mut test_file = PathBuf::from(TEST_FOLDER); test_file.push("it_move_with_progress_exist_overwrite_and_skip_exist"); let mut test_file_out = test_file.clone(); test_file.push("test.txt"); test_file_out.push("out"); test_file_out.push("test.txt"); fs_extra::dir::create_all(&test_file.parent().unwrap(), true).unwrap(); fs_extra::dir::create_all(&test_file_out.parent().unwrap(), true).unwrap(); write_all(&test_file, "test_data").unwrap(); let mut options = CopyOptions::new(); copy(&test_file, &test_file_out, &options).unwrap(); assert!(test_file.exists()); assert!(files_eq(&test_file, &test_file_out).unwrap()); options.overwrite = true; options.skip_exist = true; write_all(&test_file, "test_data2").unwrap(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); }; match move_file_with_progress(&test_file, &test_file_out, &options, func_test) { Ok(_) => { assert!(!test_file.exists()); assert!(test_file_out.exists()); assert_eq!(read_to_string(test_file_out).unwrap(), "test_data2"); () } Err(err) => panic!(err.to_string()), } } fs_extra-1.2.0/tests/lib.rs010064400017500001731000004114651360570752700140520ustar0000000000000000use std::fs::read_dir; use std::path::Path; use std::sync::mpsc::{self, TryRecvError}; use std::thread; extern crate fs_extra; use fs_extra::error::*; use fs_extra::*; fn files_eq(file1: P, file2: Q) -> bool where P: AsRef, Q: AsRef, { let content1 = fs_extra::file::read_to_string(file1).unwrap(); let content2 = fs_extra::file::read_to_string(file2).unwrap(); content1 == content2 } fn compare_dir(path_from: P, path_to: Q) -> bool where P: AsRef, Q: AsRef, { let mut path_to = path_to.as_ref().to_path_buf(); match path_from.as_ref().components().last() { None => panic!("Invalid folder from"), Some(dir_name) => { path_to.push(dir_name.as_os_str()); if !path_to.exists() { return false; } } } for entry in read_dir(&path_from).unwrap() { let entry = entry.unwrap(); let path = entry.path(); if path.is_dir() { if !compare_dir(path, &path_to) { return false; } } else { let mut path_to = path_to.to_path_buf(); match path.file_name() { None => panic!("No file name"), Some(file_name) => { path_to.push(file_name); if !path_to.exists() { return false; } else if !files_eq(&path, path_to.clone()) { return false; } } } } } true } const TEST_FOLDER: &'static str = "./tests/temp/lib"; #[test] fn it_copy_work() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_work"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); assert!(dir1.0.exists()); assert!(!dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(!sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let options = dir::CopyOptions::new(); let result = copy_items(&from_paths, &path_to, &options).unwrap(); assert_eq!(40, result); assert!(compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); } #[test] fn it_copy_source_not_exist() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_source_not_exist"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; assert!(!dir1.0.exists()); assert!(!dir1.1.exists()); assert!(!dir2.0.exists()); assert!(!dir2.1.exists()); assert!(!sub.0.exists()); assert!(!sub.1.exists()); assert!(!file1.0.exists()); assert!(!file1.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); let options = dir::CopyOptions::new(); match copy_items(&from_paths, &path_to, &options) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::NotFound => {} _ => {} }, }; } #[test] fn it_copy_exist_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_exist_overwrite"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let mut options = dir::CopyOptions::new(); options.overwrite = true; let result = copy_items(&from_paths, &path_to, &options).unwrap(); assert_eq!(40, result); assert!(compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); } #[test] fn it_copy_exist_not_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_exist_not_overwrite"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let options = dir::CopyOptions::new(); match copy_items(&from_paths, &path_to, &options) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::AlreadyExists => {} _ => panic!(format!("{}", err.to_string())), }, }; } #[test] fn it_copy_exist_skip() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_exist_skip"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let mut options = dir::CopyOptions::new(); options.skip_exist = true; let result = copy_items(&from_paths, &path_to, &options).unwrap(); assert_eq!(16, result); assert!(!compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(!files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); } #[test] fn it_copy_exist_overwrite_and_skip_exist() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_exist_overwrite_and_skip_exist"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let mut options = dir::CopyOptions::new(); options.overwrite = true; options.skip_exist = true; let result = copy_items(&from_paths, &path_to, &options).unwrap(); assert_eq!(40, result); assert!(compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); } #[test] fn it_copy_using_first_levels() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_using_first_levels"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.join("d_level_1")); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let d_level_4 = (d_level_3.0.join("d_level_4"), d_level_3.1.join("d_level_4")); let d_level_5 = (d_level_4.0.join("d_level_5"), d_level_4.1.join("d_level_5")); let d2_level_1 = (test_dir.join("d2_level_1"), path_to.join("d2_level_1")); let d2_level_2 = ( d_level_1.0.join("d2_level_2"), d_level_1.1.join("d2_level_2"), ); let d2_level_3 = ( d_level_2.0.join("d2_level_3"), d_level_2.1.join("d2_level_3"), ); let d2_level_4 = ( d_level_3.0.join("d2_level_4"), d_level_3.1.join("d2_level_4"), ); let d2_level_5 = ( d_level_4.0.join("d2_level_5"), d_level_4.1.join("d2_level_5"), ); let d3_level_1 = (test_dir.join("d3_level_1"), path_to.join("d3_level_1")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); let file4 = (d_level_4.0.join("file4.txt"), d_level_4.1.join("file4.txt")); let file5 = (d_level_5.0.join("file5.txt"), d_level_5.1.join("file5.txt")); let file21 = ( d2_level_1.0.join("file21.txt"), d2_level_1.1.join("file21.txt"), ); let file22 = ( d2_level_2.0.join("file22.txt"), d2_level_2.1.join("file22.txt"), ); let file23 = ( d2_level_3.0.join("file23.txt"), d2_level_3.1.join("file23.txt"), ); let file24 = ( d2_level_4.0.join("file24.txt"), d2_level_4.1.join("file24.txt"), ); let file25 = ( d2_level_5.0.join("file25.txt"), d2_level_5.1.join("file25.txt"), ); let file31 = ( d3_level_1.0.join("file31.txt"), d3_level_1.1.join("file31.txt"), ); dir::create_all(&d_level_1.0, true).unwrap(); dir::create_all(&d_level_2.0, true).unwrap(); dir::create_all(&d_level_3.0, true).unwrap(); dir::create_all(&d_level_4.0, true).unwrap(); dir::create_all(&d_level_5.0, true).unwrap(); dir::create_all(&path_to, true).unwrap(); dir::create_all(&d2_level_1.0, true).unwrap(); dir::create_all(&d2_level_2.0, true).unwrap(); dir::create_all(&d2_level_3.0, true).unwrap(); dir::create_all(&d2_level_4.0, true).unwrap(); dir::create_all(&d2_level_5.0, true).unwrap(); dir::create_all(&d3_level_1.0, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(d2_level_1.0.exists()); assert!(d2_level_2.0.exists()); assert!(d2_level_3.0.exists()); assert!(d2_level_4.0.exists()); assert!(d2_level_5.0.exists()); assert!(d3_level_1.0.exists()); assert!(!d_level_1.1.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); assert!(!d_level_4.1.exists()); assert!(!d_level_5.1.exists()); assert!(!d2_level_1.1.exists()); assert!(!d2_level_2.1.exists()); assert!(!d2_level_3.1.exists()); assert!(!d2_level_4.1.exists()); assert!(!d2_level_5.1.exists()); assert!(!d3_level_1.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file21.0, "2content1").unwrap(); fs_extra::file::write_all(&file22.0, "2content2").unwrap(); fs_extra::file::write_all(&file23.0, "2content3").unwrap(); fs_extra::file::write_all(&file24.0, "2content4").unwrap(); fs_extra::file::write_all(&file25.0, "2content5").unwrap(); fs_extra::file::write_all(&file31.0, "3content1").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file21.0.exists()); assert!(file22.0.exists()); assert!(file23.0.exists()); assert!(file24.0.exists()); assert!(file25.0.exists()); assert!(file31.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); assert!(!file21.1.exists()); assert!(!file22.1.exists()); assert!(!file23.1.exists()); assert!(!file24.1.exists()); assert!(!file25.1.exists()); assert!(!file31.1.exists()); let mut from_paths = Vec::new(); from_paths.push(d_level_1.0.as_path()); from_paths.push(d2_level_1.0.as_path()); from_paths.push(d3_level_1.0.as_path()); let mut options = dir::CopyOptions::new(); options.depth = 1; let result = copy_items(&from_paths, path_to, &options).unwrap(); assert_eq!(26, result); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file21.0.exists()); assert!(file22.0.exists()); assert!(file23.0.exists()); assert!(file24.0.exists()); assert!(file25.0.exists()); assert!(file31.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); assert!(file21.1.exists()); assert!(!file22.1.exists()); assert!(!file23.1.exists()); assert!(!file24.1.exists()); assert!(!file25.1.exists()); assert!(file31.1.exists()); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file21.0, &file21.1)); assert!(files_eq(&file31.0, &file31.1)); } #[test] fn it_copy_using_four_levels() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_using_four_levels"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.join("d_level_1")); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let d_level_4 = (d_level_3.0.join("d_level_4"), d_level_3.1.join("d_level_4")); let d_level_5 = (d_level_4.0.join("d_level_5"), d_level_4.1.join("d_level_5")); let d2_level_1 = (test_dir.join("d2_level_1"), path_to.join("d2_level_1")); let d2_level_2 = ( d_level_1.0.join("d2_level_2"), d_level_1.1.join("d2_level_2"), ); let d2_level_3 = ( d_level_2.0.join("d2_level_3"), d_level_2.1.join("d2_level_3"), ); let d2_level_4 = ( d_level_3.0.join("d2_level_4"), d_level_3.1.join("d2_level_4"), ); let d2_level_5 = ( d_level_4.0.join("d2_level_5"), d_level_4.1.join("d2_level_5"), ); let d3_level_1 = (test_dir.join("d3_level_1"), path_to.join("d3_level_1")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); let file4 = (d_level_4.0.join("file4.txt"), d_level_4.1.join("file4.txt")); let file5 = (d_level_5.0.join("file5.txt"), d_level_5.1.join("file5.txt")); let file21 = ( d2_level_1.0.join("file21.txt"), d2_level_1.1.join("file21.txt"), ); let file22 = ( d2_level_2.0.join("file22.txt"), d2_level_2.1.join("file22.txt"), ); let file23 = ( d2_level_3.0.join("file23.txt"), d2_level_3.1.join("file23.txt"), ); let file24 = ( d2_level_4.0.join("file24.txt"), d2_level_4.1.join("file24.txt"), ); let file25 = ( d2_level_5.0.join("file25.txt"), d2_level_5.1.join("file25.txt"), ); let file31 = ( d3_level_1.0.join("file31.txt"), d3_level_1.1.join("file31.txt"), ); dir::create_all(&d_level_1.0, true).unwrap(); dir::create_all(&d_level_2.0, true).unwrap(); dir::create_all(&d_level_3.0, true).unwrap(); dir::create_all(&d_level_4.0, true).unwrap(); dir::create_all(&d_level_5.0, true).unwrap(); dir::create_all(&path_to, true).unwrap(); dir::create_all(&d2_level_1.0, true).unwrap(); dir::create_all(&d2_level_2.0, true).unwrap(); dir::create_all(&d2_level_3.0, true).unwrap(); dir::create_all(&d2_level_4.0, true).unwrap(); dir::create_all(&d2_level_5.0, true).unwrap(); dir::create_all(&d3_level_1.0, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(d2_level_1.0.exists()); assert!(d2_level_2.0.exists()); assert!(d2_level_3.0.exists()); assert!(d2_level_4.0.exists()); assert!(d2_level_5.0.exists()); assert!(d3_level_1.0.exists()); assert!(!d_level_1.1.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); assert!(!d_level_4.1.exists()); assert!(!d_level_5.1.exists()); assert!(!d2_level_1.1.exists()); assert!(!d2_level_2.1.exists()); assert!(!d2_level_3.1.exists()); assert!(!d2_level_4.1.exists()); assert!(!d2_level_5.1.exists()); assert!(!d3_level_1.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file21.0, "2content1").unwrap(); fs_extra::file::write_all(&file22.0, "2content2").unwrap(); fs_extra::file::write_all(&file23.0, "2content3").unwrap(); fs_extra::file::write_all(&file24.0, "2content4").unwrap(); fs_extra::file::write_all(&file25.0, "2content5").unwrap(); fs_extra::file::write_all(&file31.0, "3content1").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file21.0.exists()); assert!(file22.0.exists()); assert!(file23.0.exists()); assert!(file24.0.exists()); assert!(file25.0.exists()); assert!(file31.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); assert!(!file21.1.exists()); assert!(!file22.1.exists()); assert!(!file23.1.exists()); assert!(!file24.1.exists()); assert!(!file25.1.exists()); assert!(!file31.1.exists()); let mut from_paths = Vec::new(); from_paths.push(d_level_1.0.as_path()); from_paths.push(d2_level_1.0.as_path()); from_paths.push(d3_level_1.0.as_path()); let mut options = dir::CopyOptions::new(); options.depth = 4; let result = copy_items(&from_paths, path_to, &options).unwrap(); assert_eq!(77, result); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file21.0.exists()); assert!(file22.0.exists()); assert!(file23.0.exists()); assert!(file24.0.exists()); assert!(file25.0.exists()); assert!(file31.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); assert!(file21.1.exists()); assert!(file22.1.exists()); assert!(file23.1.exists()); assert!(file24.1.exists()); assert!(!file25.1.exists()); assert!(file31.1.exists()); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file21.0, &file21.1)); assert!(files_eq(&file31.0, &file31.1)); } #[test] fn it_copy_content_only_opton() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_content_only_opton"); let path_to = test_dir.join("out"); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let mut options = dir::CopyOptions::new(); options.content_only = true; match copy_items(&vec![&file1.0], &file1.1, &options) { Err(err) => match err.kind { ErrorKind::Other => { assert_eq!(1, 1); } _ => { panic!(format!("wrong error {}", err.to_string())); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_copy_progress_work() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_progress_work"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); assert!(dir1.0.exists()); assert!(!dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(!sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content22").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); let options = dir::CopyOptions::new(); let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(41, result); assert!(compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "file2.txt" { assert_eq!(9, process_info.file_total_bytes); assert_eq!(41, process_info.total_bytes); } else if process_info.file_name == "file1.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(41, process_info.total_bytes); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_copy_with_progress_work_dif_buf_size() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_work_dif_buf_size"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); assert!(dir1.0.exists()); assert!(!dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(!sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); let mut options = dir::CopyOptions::new(); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut from_paths = Vec::new(); from_paths.push(file1.0.as_path().to_str().unwrap().to_string()); from_paths.push(file2.0.as_path().to_str().unwrap().to_string()); from_paths.push(dir1.0.as_path().to_str().unwrap().to_string()); from_paths.push(dir2.0.as_path().to_str().unwrap().to_string()); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(40, result); assert!(compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); let mut options = dir::CopyOptions::new(); options.buffer_size = 2; options.overwrite = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(40, result); assert!(compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); }).join(); for i in 1..5 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i * 2, process_info.file_bytes_copied); assert_eq!(i * 2, process_info.copied_bytes); assert_eq!(8, process_info.file_total_bytes); assert_eq!(40, process_info.total_bytes); } for i in 1..5 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i * 2 + 8, process_info.copied_bytes); assert_eq!(i * 2, process_info.file_bytes_copied); assert_eq!(8, process_info.file_total_bytes); assert_eq!(40, process_info.total_bytes); } match result { Ok(_) => {} Err(err) => panic!(err), } }).join(); for i in 1..9 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i, process_info.file_bytes_copied); assert_eq!(i, process_info.copied_bytes); assert_eq!(8, process_info.file_total_bytes); assert_eq!(40, process_info.total_bytes); } for i in 1..9 { let process_info: TransitProcess = rx.recv().unwrap(); assert_eq!(i + 8, process_info.copied_bytes); assert_eq!(i, process_info.file_bytes_copied); assert_eq!(8, process_info.file_total_bytes); assert_eq!(40, process_info.total_bytes); } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_copy_with_progress_source_not_exist() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_source_not_exist"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; assert!(!dir1.0.exists()); assert!(!dir1.1.exists()); assert!(!dir2.0.exists()); assert!(!dir2.1.exists()); assert!(!sub.0.exists()); assert!(!sub.1.exists()); assert!(!file1.0.exists()); assert!(!file1.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); dir::TransitProcessResult::ContinueOrAbort }; let options = dir::CopyOptions::new(); match copy_items_with_progress(&from_paths, &path_to, &options, func_test) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::NotFound => {} _ => {} }, }; } #[test] fn it_copy_with_progress_exist_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_overwrite"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut options = dir::CopyOptions::new(); options.overwrite = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(40, result); assert!(compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_copy_with_progress_exist_not_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_not_overwrite"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let options = dir::CopyOptions::new(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); dir::TransitProcessResult::ContinueOrAbort }; match copy_items_with_progress(&from_paths, &path_to, &options, func_test) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::AlreadyExists => {} _ => panic!(format!("{}", err.to_string())), }, }; } #[test] fn it_copy_with_progress_exist_skip_exist() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_skip_exist"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut options = dir::CopyOptions::new(); options.skip_exist = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(16, result); assert!(!compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(!files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_copy_with_progress_exist_overwrite_and_skip_exist() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_overwrite_and_skip_exist"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut options = dir::CopyOptions::new(); options.overwrite = true; options.skip_exist = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(40, result); assert!(compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_copy_with_progress_using_first_levels() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_using_first_levels"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.join("d_level_1")); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let d_level_4 = (d_level_3.0.join("d_level_4"), d_level_3.1.join("d_level_4")); let d_level_5 = (d_level_4.0.join("d_level_5"), d_level_4.1.join("d_level_5")); let d2_level_1 = (test_dir.join("d2_level_1"), path_to.join("d2_level_1")); let d2_level_2 = ( d_level_1.0.join("d2_level_2"), d_level_1.1.join("d2_level_2"), ); let d2_level_3 = ( d_level_2.0.join("d2_level_3"), d_level_2.1.join("d2_level_3"), ); let d2_level_4 = ( d_level_3.0.join("d2_level_4"), d_level_3.1.join("d2_level_4"), ); let d2_level_5 = ( d_level_4.0.join("d2_level_5"), d_level_4.1.join("d2_level_5"), ); let d3_level_1 = (test_dir.join("d3_level_1"), path_to.join("d3_level_1")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); let file4 = (d_level_4.0.join("file4.txt"), d_level_4.1.join("file4.txt")); let file5 = (d_level_5.0.join("file5.txt"), d_level_5.1.join("file5.txt")); let file21 = ( d2_level_1.0.join("file21.txt"), d2_level_1.1.join("file21.txt"), ); let file22 = ( d2_level_2.0.join("file22.txt"), d2_level_2.1.join("file22.txt"), ); let file23 = ( d2_level_3.0.join("file23.txt"), d2_level_3.1.join("file23.txt"), ); let file24 = ( d2_level_4.0.join("file24.txt"), d2_level_4.1.join("file24.txt"), ); let file25 = ( d2_level_5.0.join("file25.txt"), d2_level_5.1.join("file25.txt"), ); let file31 = ( d3_level_1.0.join("file31.txt"), d3_level_1.1.join("file31.txt"), ); dir::create_all(&d_level_1.0, true).unwrap(); dir::create_all(&d_level_2.0, true).unwrap(); dir::create_all(&d_level_3.0, true).unwrap(); dir::create_all(&d_level_4.0, true).unwrap(); dir::create_all(&d_level_5.0, true).unwrap(); dir::create_all(&path_to, true).unwrap(); dir::create_all(&d2_level_1.0, true).unwrap(); dir::create_all(&d2_level_2.0, true).unwrap(); dir::create_all(&d2_level_3.0, true).unwrap(); dir::create_all(&d2_level_4.0, true).unwrap(); dir::create_all(&d2_level_5.0, true).unwrap(); dir::create_all(&d3_level_1.0, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(d2_level_1.0.exists()); assert!(d2_level_2.0.exists()); assert!(d2_level_3.0.exists()); assert!(d2_level_4.0.exists()); assert!(d2_level_5.0.exists()); assert!(d3_level_1.0.exists()); assert!(!d_level_1.1.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); assert!(!d_level_4.1.exists()); assert!(!d_level_5.1.exists()); assert!(!d2_level_1.1.exists()); assert!(!d2_level_2.1.exists()); assert!(!d2_level_3.1.exists()); assert!(!d2_level_4.1.exists()); assert!(!d2_level_5.1.exists()); assert!(!d3_level_1.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file21.0, "2content1").unwrap(); fs_extra::file::write_all(&file22.0, "2content2").unwrap(); fs_extra::file::write_all(&file23.0, "2content3").unwrap(); fs_extra::file::write_all(&file24.0, "2content4").unwrap(); fs_extra::file::write_all(&file25.0, "2content5").unwrap(); fs_extra::file::write_all(&file31.0, "3content1").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file21.0.exists()); assert!(file22.0.exists()); assert!(file23.0.exists()); assert!(file24.0.exists()); assert!(file25.0.exists()); assert!(file31.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); assert!(!file21.1.exists()); assert!(!file22.1.exists()); assert!(!file23.1.exists()); assert!(!file24.1.exists()); assert!(!file25.1.exists()); assert!(!file31.1.exists()); let mut options = dir::CopyOptions::new(); options.depth = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut from_paths = Vec::new(); from_paths.push(d_level_1.0.as_path()); from_paths.push(d2_level_1.0.as_path()); from_paths.push(d3_level_1.0.as_path()); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(26, result); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file21.0.exists()); assert!(file22.0.exists()); assert!(file23.0.exists()); assert!(file24.0.exists()); assert!(file25.0.exists()); assert!(file31.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); assert!(file21.1.exists()); assert!(!file22.1.exists()); assert!(!file23.1.exists()); assert!(!file24.1.exists()); assert!(!file25.1.exists()); assert!(file31.1.exists()); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file21.0, &file21.1)); assert!(files_eq(&file31.0, &file31.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_copy_with_progress_using_four_levels() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_using_four_levels"); let path_to = test_dir.join("out"); let d_level_1 = (test_dir.join("d_level_1"), path_to.join("d_level_1")); let d_level_2 = (d_level_1.0.join("d_level_2"), d_level_1.1.join("d_level_2")); let d_level_3 = (d_level_2.0.join("d_level_3"), d_level_2.1.join("d_level_3")); let d_level_4 = (d_level_3.0.join("d_level_4"), d_level_3.1.join("d_level_4")); let d_level_5 = (d_level_4.0.join("d_level_5"), d_level_4.1.join("d_level_5")); let d2_level_1 = (test_dir.join("d2_level_1"), path_to.join("d2_level_1")); let d2_level_2 = ( d_level_1.0.join("d2_level_2"), d_level_1.1.join("d2_level_2"), ); let d2_level_3 = ( d_level_2.0.join("d2_level_3"), d_level_2.1.join("d2_level_3"), ); let d2_level_4 = ( d_level_3.0.join("d2_level_4"), d_level_3.1.join("d2_level_4"), ); let d2_level_5 = ( d_level_4.0.join("d2_level_5"), d_level_4.1.join("d2_level_5"), ); let d3_level_1 = (test_dir.join("d3_level_1"), path_to.join("d3_level_1")); let file1 = (d_level_1.0.join("file1.txt"), d_level_1.1.join("file1.txt")); let file2 = (d_level_2.0.join("file2.txt"), d_level_2.1.join("file2.txt")); let file3 = (d_level_3.0.join("file3.txt"), d_level_3.1.join("file3.txt")); let file4 = (d_level_4.0.join("file4.txt"), d_level_4.1.join("file4.txt")); let file5 = (d_level_5.0.join("file5.txt"), d_level_5.1.join("file5.txt")); let file21 = ( d2_level_1.0.join("file21.txt"), d2_level_1.1.join("file21.txt"), ); let file22 = ( d2_level_2.0.join("file22.txt"), d2_level_2.1.join("file22.txt"), ); let file23 = ( d2_level_3.0.join("file23.txt"), d2_level_3.1.join("file23.txt"), ); let file24 = ( d2_level_4.0.join("file24.txt"), d2_level_4.1.join("file24.txt"), ); let file25 = ( d2_level_5.0.join("file25.txt"), d2_level_5.1.join("file25.txt"), ); let file31 = ( d3_level_1.0.join("file31.txt"), d3_level_1.1.join("file31.txt"), ); dir::create_all(&d_level_1.0, true).unwrap(); dir::create_all(&d_level_2.0, true).unwrap(); dir::create_all(&d_level_3.0, true).unwrap(); dir::create_all(&d_level_4.0, true).unwrap(); dir::create_all(&d_level_5.0, true).unwrap(); dir::create_all(&path_to, true).unwrap(); dir::create_all(&d2_level_1.0, true).unwrap(); dir::create_all(&d2_level_2.0, true).unwrap(); dir::create_all(&d2_level_3.0, true).unwrap(); dir::create_all(&d2_level_4.0, true).unwrap(); dir::create_all(&d2_level_5.0, true).unwrap(); dir::create_all(&d3_level_1.0, true).unwrap(); assert!(path_to.exists()); assert!(d_level_1.0.exists()); assert!(d_level_2.0.exists()); assert!(d_level_3.0.exists()); assert!(d_level_4.0.exists()); assert!(d_level_5.0.exists()); assert!(d2_level_1.0.exists()); assert!(d2_level_2.0.exists()); assert!(d2_level_3.0.exists()); assert!(d2_level_4.0.exists()); assert!(d2_level_5.0.exists()); assert!(d3_level_1.0.exists()); assert!(!d_level_1.1.exists()); assert!(!d_level_2.1.exists()); assert!(!d_level_3.1.exists()); assert!(!d_level_4.1.exists()); assert!(!d_level_5.1.exists()); assert!(!d2_level_1.1.exists()); assert!(!d2_level_2.1.exists()); assert!(!d2_level_3.1.exists()); assert!(!d2_level_4.1.exists()); assert!(!d2_level_5.1.exists()); assert!(!d3_level_1.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file21.0, "2content1").unwrap(); fs_extra::file::write_all(&file22.0, "2content2").unwrap(); fs_extra::file::write_all(&file23.0, "2content3").unwrap(); fs_extra::file::write_all(&file24.0, "2content4").unwrap(); fs_extra::file::write_all(&file25.0, "2content5").unwrap(); fs_extra::file::write_all(&file31.0, "3content1").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file21.0.exists()); assert!(file22.0.exists()); assert!(file23.0.exists()); assert!(file24.0.exists()); assert!(file25.0.exists()); assert!(file31.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); assert!(!file21.1.exists()); assert!(!file22.1.exists()); assert!(!file23.1.exists()); assert!(!file24.1.exists()); assert!(!file25.1.exists()); assert!(!file31.1.exists()); let mut options = dir::CopyOptions::new(); options.depth = 4; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut from_paths = Vec::new(); from_paths.push(d_level_1.0.as_path()); from_paths.push(d2_level_1.0.as_path()); from_paths.push(d3_level_1.0.as_path()); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(77, result); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file21.0.exists()); assert!(file22.0.exists()); assert!(file23.0.exists()); assert!(file24.0.exists()); assert!(file25.0.exists()); assert!(file31.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); assert!(file21.1.exists()); assert!(file22.1.exists()); assert!(file23.1.exists()); assert!(file24.1.exists()); assert!(!file25.1.exists()); assert!(file31.1.exists()); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file21.0, &file21.1)); assert!(files_eq(&file31.0, &file31.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_copy_with_progress_content_only_opton() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_content_only_opton"); let path_to = test_dir.join("out"); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let mut options = dir::CopyOptions::new(); options.content_only = true; let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); dir::TransitProcessResult::ContinueOrAbort }; match copy_items_with_progress(&vec![&file1.0], &file1.1, &options, func_test) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::Other => {} _ => panic!(format!("wrong error {}", err.to_string())), }, }; } #[test] fn it_move_work() { let test_dir = Path::new(TEST_FOLDER).join("it_move_work"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); assert!(dir1.0.exists()); assert!(!dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(!sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let options = dir::CopyOptions::new(); let result = move_items(&from_paths, &path_to, &options).unwrap(); assert_eq!(40, result); assert!(!file1.0.exists()); assert!(!file2.0.exists()); assert!(!file3.0.exists()); assert!(!file4.0.exists()); assert!(!file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); } #[test] fn it_move_source_not_exist() { let test_dir = Path::new(TEST_FOLDER).join("it_move_source_not_exist"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; assert!(!dir1.0.exists()); assert!(!dir1.1.exists()); assert!(!dir2.0.exists()); assert!(!dir2.1.exists()); assert!(!sub.0.exists()); assert!(!sub.1.exists()); assert!(!file1.0.exists()); assert!(!file1.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); let options = dir::CopyOptions::new(); match move_items(&from_paths, &path_to, &options) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::NotFound => {} _ => {} }, }; } #[test] fn it_move_exist_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_move_exist_overwrite"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let mut options = dir::CopyOptions::new(); options.overwrite = true; let result = move_items(&from_paths, &path_to, &options).unwrap(); assert_eq!(40, result); assert!(!file1.0.exists()); assert!(!file2.0.exists()); assert!(!file3.0.exists()); assert!(!file4.0.exists()); assert!(!file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); } #[test] fn it_move_exist_not_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_move_exist_not_overwrite"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let options = dir::CopyOptions::new(); match move_items(&from_paths, &path_to, &options) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::AlreadyExists => {} _ => panic!(format!("{}", err.to_string())), }, }; } #[test] fn it_move_exist_skip() { let test_dir = Path::new(TEST_FOLDER).join("it_move_exist_skip"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let mut options = dir::CopyOptions::new(); options.skip_exist = true; let result = move_items(&from_paths, &path_to, &options).unwrap(); assert_eq!(16, result); assert!(!files_eq(&file1.0, &file1.1)); assert!(!file2.0.exists()); assert!(!files_eq(&file3.0, &file3.1)); assert!(!files_eq(&file4.0, &file4.1)); assert!(!file5.0.exists()); } #[test] fn it_move_exist_overwrite_and_skip_exist() { let test_dir = Path::new(TEST_FOLDER).join("it_move_exist_overwrite_and_skip_exist"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let mut options = dir::CopyOptions::new(); options.overwrite = true; options.skip_exist = true; let result = move_items(&from_paths, &path_to, &options).unwrap(); assert_eq!(40, result); assert!(!file1.0.exists()); assert!(!file2.0.exists()); assert!(!file3.0.exists()); assert!(!file4.0.exists()); assert!(!file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); } #[test] fn it_move_content_only_option() { let test_dir = Path::new(TEST_FOLDER).join("it_move_content_only_option"); let path_to = test_dir.join("out"); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let mut options = dir::CopyOptions::new(); options.content_only = true; match move_items(&vec![&file1.0], &file1.1, &options) { Err(err) => match err.kind { ErrorKind::Other => { assert_eq!(1, 1); } _ => { panic!(format!("wrong error {}", err.to_string())); } }, Ok(_) => { panic!("should be error"); } } } #[test] fn it_move_progress_work() { let test_dir = Path::new(TEST_FOLDER).join("it_move_progress_work"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); assert!(dir1.0.exists()); assert!(!dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(!sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content22").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(!file1.1.exists()); assert!(!file2.1.exists()); assert!(!file3.1.exists()); assert!(!file4.1.exists()); assert!(!file5.1.exists()); let options = dir::CopyOptions::new(); let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = move_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(41, result); assert!(!file1.0.exists()); assert!(!file2.0.exists()); assert!(!file3.0.exists()); assert!(!file4.0.exists()); assert!(!file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); }).join(); loop { match rx.try_recv() { Ok(process_info) => { if process_info.file_name == "file2.txt" { assert_eq!(9, process_info.file_total_bytes); assert_eq!(41, process_info.total_bytes); } else if process_info.file_name == "file1.txt" { assert_eq!(8, process_info.file_total_bytes); assert_eq!(41, process_info.total_bytes); } } Err(TryRecvError::Disconnected) => { break; } Err(TryRecvError::Empty) => {} } } match result { Ok(_) => {} Err(err) => panic!(err), } } #[test] fn it_move_with_progress_source_not_exist() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_source_not_exist"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; assert!(!dir1.0.exists()); assert!(!dir1.1.exists()); assert!(!dir2.0.exists()); assert!(!dir2.1.exists()); assert!(!sub.0.exists()); assert!(!sub.1.exists()); assert!(!file1.0.exists()); assert!(!file1.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); dir::TransitProcessResult::ContinueOrAbort }; let options = dir::CopyOptions::new(); match move_items_with_progress(&from_paths, &path_to, &options, func_test) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::NotFound => {} _ => {} }, }; } #[test] fn it_move_with_progress_exist_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_overwrite"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut options = dir::CopyOptions::new(); options.overwrite = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = move_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(40, result); assert!(!file1.0.exists()); assert!(!file2.0.exists()); assert!(!file3.0.exists()); assert!(!file4.0.exists()); assert!(!file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_move_with_progress_exist_not_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_not_overwrite"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let options = dir::CopyOptions::new(); let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); dir::TransitProcessResult::ContinueOrAbort }; match move_items_with_progress(&from_paths, &path_to, &options, func_test) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::AlreadyExists => {} _ => panic!(format!("{}", err.to_string())), }, }; } #[test] fn it_move_with_progress_exist_skip_exist() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_skip_exist"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); dir::create_all(&dir2.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); file::write_all(&file5.1, "old content5").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); let mut options = dir::CopyOptions::new(); options.skip_exist = true; options.overwrite = false; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = move_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(8, result); assert!(file1.0.exists()); assert!(!file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); assert!(!files_eq(&file1.0, &file1.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_move_with_progress_exist_overwrite_and_skip_exist() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_overwrite_and_skip_exist"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); match dir::create_all(&path_to, true) { Ok(_) => {} Err(_) => {} }; dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(!dir2.1.exists()); assert!(sub.0.exists()); assert!(sub.1.exists()); file::write_all(&file1.0, "content1").unwrap(); file::write_all(&file2.0, "content2").unwrap(); file::write_all(&file3.0, "content3").unwrap(); file::write_all(&file4.0, "content4").unwrap(); file::write_all(&file5.0, "content5").unwrap(); file::write_all(&file1.1, "old content1").unwrap(); file::write_all(&file3.1, "old content3").unwrap(); file::write_all(&file4.1, "old content4").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(!file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(!file5.1.exists()); let mut options = dir::CopyOptions::new(); options.overwrite = true; options.skip_exist = true; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let func_test = |process_info: TransitProcess| { tx.send(process_info).unwrap(); dir::TransitProcessResult::ContinueOrAbort }; let result = move_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); assert_eq!(40, result); assert!(!file1.0.exists()); assert!(!file2.0.exists()); assert!(!file3.0.exists()); assert!(!file4.0.exists()); assert!(!file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } match rx.recv() { Err(_) => panic!("Errors should not be!"), _ => {} } } #[test] fn it_move_with_progress_content_only_option() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_content_only_option"); let path_to = test_dir.join("out"); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let mut options = dir::CopyOptions::new(); options.content_only = true; let func_test = |process_info: TransitProcess| { println!("{}", process_info.total_bytes); dir::TransitProcessResult::ContinueOrAbort }; match move_items_with_progress(&vec![&file1.0], &file1.1, &options, func_test) { Ok(_) => panic!("Should be a error!"), Err(err) => match err.kind { ErrorKind::Other => {} _ => panic!(format!("wrong error {}", err.to_string())), }, }; } #[test] fn it_remove_work() { let test_dir = Path::new(TEST_FOLDER).join("it_remove_work"); let dir1 = test_dir.join("dir1"); let dir2 = test_dir.join("dir2"); let sub = dir1.join("sub"); let file1 = test_dir.join("file1.txt"); let file2 = test_dir.join("file2.txt"); let file3 = dir1.join("file3.txt"); let file4 = sub.join("file4.txt"); let file5 = dir2.join("file5.txt"); dir::create_all(&dir1, true).unwrap(); dir::create_all(&dir2, true).unwrap(); dir::create_all(&sub, true).unwrap(); assert!(dir1.exists()); assert!(dir2.exists()); assert!(sub.exists()); file::write_all(&file1, "content1").unwrap(); file::write_all(&file2, "content2").unwrap(); file::write_all(&file3, "content3").unwrap(); file::write_all(&file4, "content4").unwrap(); file::write_all(&file5, "content5").unwrap(); assert!(file1.exists()); assert!(file2.exists()); assert!(file3.exists()); assert!(file4.exists()); assert!(file5.exists()); let mut from_paths = Vec::new(); from_paths.push(dir1.as_path()); from_paths.push(dir2.as_path()); from_paths.push(file1.as_path()); from_paths.push(file2.as_path()); remove_items(&from_paths).unwrap(); assert!(!file1.exists()); assert!(!file2.exists()); assert!(!file3.exists()); assert!(!file4.exists()); assert!(!file5.exists()); } #[test] fn it_copy_with_progress_exist_user_decide_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_user_decide_overwrite"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir1.1, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&dir2.1, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(&dir1.0.exists()); assert!(&dir1.1.exists()); assert!(&dir2.0.exists()); assert!(&dir2.1.exists()); assert!(&sub.0.exists()); assert!(&sub.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file1.1, "old content11").unwrap(); fs_extra::file::write_all(&file2.1, "old content12").unwrap(); fs_extra::file::write_all(&file3.1, "old content13").unwrap(); fs_extra::file::write_all(&file4.1, "old content14").unwrap(); fs_extra::file::write_all(&file5.1, "old content15").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); let mut options = dir::CopyOptions::new(); assert!(!compare_dir(&dir1.0, &dir1.1)); assert!(!compare_dir(&dir2.0, &dir2.1)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let result: u64; { let func_test = |process_info: TransitProcess| { let result: dir::TransitProcessResult; match process_info.state { dir::TransitState::Exists => { count_exist_files += 1; result = dir::TransitProcessResult::Overwrite; tx.send(process_info).unwrap(); } _ => result = dir::TransitProcessResult::Abort, }; result }; result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); } assert_eq!(5, count_exist_files); assert_eq!(40, result); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(dir2.1.exists()); assert!(compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_copy_with_progress_exist_user_decide_overwrite_all() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_user_decide_overwrite_all"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir1.1, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&dir2.1, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(&dir1.0.exists()); assert!(&dir1.1.exists()); assert!(&dir2.0.exists()); assert!(&dir2.1.exists()); assert!(&sub.0.exists()); assert!(&sub.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file1.1, "old content11").unwrap(); fs_extra::file::write_all(&file2.1, "old content12").unwrap(); fs_extra::file::write_all(&file3.1, "old content13").unwrap(); fs_extra::file::write_all(&file4.1, "old content14").unwrap(); fs_extra::file::write_all(&file5.1, "old content15").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); let mut options = dir::CopyOptions::new(); assert!(!compare_dir(&dir1.0, &dir1.1)); assert!(!compare_dir(&dir2.0, &dir2.1)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let result: u64; { let func_test = |process_info: TransitProcess| { let result: dir::TransitProcessResult; match process_info.state { dir::TransitState::Exists => { count_exist_files += 1; result = dir::TransitProcessResult::OverwriteAll; tx.send(process_info).unwrap(); } _ => result = dir::TransitProcessResult::Abort, }; result }; result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); } assert_eq!(1, count_exist_files); assert_eq!(40, result); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(dir2.1.exists()); assert!(compare_dir(&dir1.0, &path_to)); assert!(compare_dir(&dir2.0, &path_to)); assert!(files_eq(&file1.0, &file1.1)); assert!(files_eq(&file2.0, &file2.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_copy_with_progress_exist_user_decide_skip() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_user_decide_skip"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir1.1, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&dir2.1, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(&dir1.0.exists()); assert!(&dir1.1.exists()); assert!(&dir2.0.exists()); assert!(&dir2.1.exists()); assert!(&sub.0.exists()); assert!(&sub.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file1.1, "old content11").unwrap(); fs_extra::file::write_all(&file2.1, "old content12").unwrap(); fs_extra::file::write_all(&file3.1, "old content13").unwrap(); fs_extra::file::write_all(&file4.1, "old content14").unwrap(); fs_extra::file::write_all(&file5.1, "old content15").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); let mut options = dir::CopyOptions::new(); assert!(!compare_dir(&dir1.0, &dir1.1)); assert!(!compare_dir(&dir2.0, &dir2.1)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let result: u64; { let func_test = |process_info: TransitProcess| { let result: dir::TransitProcessResult; match process_info.state { dir::TransitState::Exists => { count_exist_files += 1; result = dir::TransitProcessResult::Skip; tx.send(process_info).unwrap(); } _ => result = dir::TransitProcessResult::Abort, }; result }; result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); } assert_eq!(5, count_exist_files); assert_eq!(0, result); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(dir2.1.exists()); assert!(!compare_dir(&dir1.0, &path_to)); assert!(!compare_dir(&dir2.0, &path_to)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_copy_with_progress_exist_user_decide_skip_all() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_user_decide_skip_all"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir1.1, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&dir2.1, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(&dir1.0.exists()); assert!(&dir1.1.exists()); assert!(&dir2.0.exists()); assert!(&dir2.1.exists()); assert!(&sub.0.exists()); assert!(&sub.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file1.1, "old content11").unwrap(); fs_extra::file::write_all(&file2.1, "old content12").unwrap(); fs_extra::file::write_all(&file3.1, "old content13").unwrap(); fs_extra::file::write_all(&file4.1, "old content14").unwrap(); fs_extra::file::write_all(&file5.1, "old content15").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); let mut options = dir::CopyOptions::new(); assert!(!compare_dir(&dir1.0, &dir1.1)); assert!(!compare_dir(&dir2.0, &dir2.1)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let result: u64; { let func_test = |process_info: TransitProcess| { let result: dir::TransitProcessResult; match process_info.state { dir::TransitState::Exists => { count_exist_files += 1; result = dir::TransitProcessResult::SkipAll; tx.send(process_info).unwrap(); } _ => result = dir::TransitProcessResult::Abort, }; result }; result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); } assert_eq!(1, count_exist_files); assert_eq!(0, result); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(dir2.1.exists()); assert!(!compare_dir(&dir1.0, &path_to)); assert!(!compare_dir(&dir2.0, &path_to)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_copy_with_progress_exist_user_decide_retry() { let test_dir = Path::new(TEST_FOLDER).join("it_copy_with_progress_exist_user_decide_retry"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir1.1, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&dir2.1, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(&dir1.0.exists()); assert!(&dir1.1.exists()); assert!(&dir2.0.exists()); assert!(&dir2.1.exists()); assert!(&sub.0.exists()); assert!(&sub.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file1.1, "old content11").unwrap(); fs_extra::file::write_all(&file2.1, "old content12").unwrap(); fs_extra::file::write_all(&file3.1, "old content13").unwrap(); fs_extra::file::write_all(&file4.1, "old content14").unwrap(); fs_extra::file::write_all(&file5.1, "old content15").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); let mut options = dir::CopyOptions::new(); assert!(!compare_dir(&dir1.0, &dir1.1)); assert!(!compare_dir(&dir2.0, &dir2.1)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let result: u64; { let func_test = |process_info: TransitProcess| { let result: dir::TransitProcessResult; match process_info.state { dir::TransitState::Exists => { if count_exist_files == 3 || count_exist_files > 6 { result = dir::TransitProcessResult::Skip; } else { result = dir::TransitProcessResult::Retry; } count_exist_files += 1; tx.send(process_info).unwrap(); } _ => result = dir::TransitProcessResult::Abort, }; result }; result = copy_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); } assert_eq!(11, count_exist_files); assert_eq!(0, result); assert!(dir1.0.exists()); assert!(dir1.1.exists()); assert!(dir2.0.exists()); assert!(dir2.1.exists()); assert!(!compare_dir(&dir1.0, &path_to)); assert!(!compare_dir(&dir2.0, &path_to)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_move_with_progress_exist_user_decide_overwrite() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_user_decide_overwrite"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir1.1, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&dir2.1, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(&dir1.0.exists()); assert!(&dir1.1.exists()); assert!(&dir2.0.exists()); assert!(&dir2.1.exists()); assert!(&sub.0.exists()); assert!(&sub.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file1.1, "old content11").unwrap(); fs_extra::file::write_all(&file2.1, "old content12").unwrap(); fs_extra::file::write_all(&file3.1, "old content13").unwrap(); fs_extra::file::write_all(&file4.1, "old content14").unwrap(); fs_extra::file::write_all(&file5.1, "old content15").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); let mut options = dir::CopyOptions::new(); assert!(!compare_dir(&dir1.0, &dir1.1)); assert!(!compare_dir(&dir2.0, &dir2.1)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let result: u64; { let func_test = |process_info: TransitProcess| { let result: dir::TransitProcessResult; match process_info.state { dir::TransitState::Exists => { count_exist_files += 1; result = dir::TransitProcessResult::Overwrite; tx.send(process_info).unwrap(); } _ => result = dir::TransitProcessResult::Abort, }; result }; result = move_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); } assert_eq!(5, count_exist_files); assert_eq!(40, result); assert!(!dir1.0.exists()); assert!(!dir2.0.exists()); assert!(dir1.1.exists()); assert!(dir2.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_move_with_progress_exist_user_decide_overwrite_all() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_user_decide_overwrite_all"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir1.1, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&dir2.1, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(&dir1.0.exists()); assert!(&dir1.1.exists()); assert!(&dir2.0.exists()); assert!(&dir2.1.exists()); assert!(&sub.0.exists()); assert!(&sub.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file1.1, "old content11").unwrap(); fs_extra::file::write_all(&file2.1, "old content12").unwrap(); fs_extra::file::write_all(&file3.1, "old content13").unwrap(); fs_extra::file::write_all(&file4.1, "old content14").unwrap(); fs_extra::file::write_all(&file5.1, "old content15").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); let mut options = dir::CopyOptions::new(); assert!(!compare_dir(&dir1.0, &dir1.1)); assert!(!compare_dir(&dir2.0, &dir2.1)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let result: u64; { let func_test = |process_info: TransitProcess| { let result: dir::TransitProcessResult; match process_info.state { dir::TransitState::Exists => { count_exist_files += 1; result = dir::TransitProcessResult::OverwriteAll; tx.send(process_info).unwrap(); } _ => result = dir::TransitProcessResult::Abort, }; result }; result = move_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); } assert_eq!(1, count_exist_files); assert_eq!(40, result); assert!(!dir1.0.exists()); assert!(!dir2.0.exists()); assert!(dir1.1.exists()); assert!(dir2.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_move_with_progress_exist_user_decide_skip() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_user_decide_skip"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir1.1, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&dir2.1, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(&dir1.0.exists()); assert!(&dir1.1.exists()); assert!(&dir2.0.exists()); assert!(&dir2.1.exists()); assert!(&sub.0.exists()); assert!(&sub.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file1.1, "old content11").unwrap(); fs_extra::file::write_all(&file2.1, "old content12").unwrap(); fs_extra::file::write_all(&file3.1, "old content13").unwrap(); fs_extra::file::write_all(&file4.1, "old content14").unwrap(); fs_extra::file::write_all(&file5.1, "old content15").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); let mut options = dir::CopyOptions::new(); assert!(!compare_dir(&dir1.0, &dir1.1)); assert!(!compare_dir(&dir2.0, &dir2.1)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let result: u64; { let func_test = |process_info: TransitProcess| { let result: dir::TransitProcessResult; match process_info.state { dir::TransitState::Exists => { count_exist_files += 1; result = dir::TransitProcessResult::Skip; tx.send(process_info).unwrap(); } _ => result = dir::TransitProcessResult::Abort, }; result }; result = move_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); } assert_eq!(5, count_exist_files); assert_eq!(0, result); assert!(dir1.0.exists()); assert!(dir2.0.exists()); assert!(dir1.1.exists()); assert!(dir2.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_move_with_progress_exist_user_decide_skip_all() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_user_decide_skip_all"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir1.1, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&dir2.1, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(&dir1.0.exists()); assert!(&dir1.1.exists()); assert!(&dir2.0.exists()); assert!(&dir2.1.exists()); assert!(&sub.0.exists()); assert!(&sub.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file1.1, "old content11").unwrap(); fs_extra::file::write_all(&file2.1, "old content12").unwrap(); fs_extra::file::write_all(&file3.1, "old content13").unwrap(); fs_extra::file::write_all(&file4.1, "old content14").unwrap(); fs_extra::file::write_all(&file5.1, "old content15").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); let mut options = dir::CopyOptions::new(); assert!(!compare_dir(&dir1.0, &dir1.1)); assert!(!compare_dir(&dir2.0, &dir2.1)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let result: u64; { let func_test = |process_info: TransitProcess| { let result: dir::TransitProcessResult; match process_info.state { dir::TransitState::Exists => { count_exist_files += 1; result = dir::TransitProcessResult::SkipAll; tx.send(process_info).unwrap(); } _ => result = dir::TransitProcessResult::Abort, }; result }; result = move_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); } assert_eq!(1, count_exist_files); assert_eq!(0, result); assert!(dir1.0.exists()); assert!(dir2.0.exists()); assert!(dir1.1.exists()); assert!(dir2.1.exists()); assert!(file1.0.exists()); assert!(file2.0.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); } #[test] fn it_move_with_progress_exist_user_decide_retry() { let test_dir = Path::new(TEST_FOLDER).join("it_move_with_progress_exist_user_decide_retry"); let path_to = test_dir.join("out"); let dir1 = (test_dir.join("dir1"), path_to.join("dir1")); let dir2 = (test_dir.join("dir2"), path_to.join("dir2")); let sub = (dir1.0.join("sub"), dir1.1.join("sub")); let file1 = (test_dir.join("file1.txt"), path_to.join("file1.txt")); let file2 = (test_dir.join("file2.txt"), path_to.join("file2.txt")); let file3 = (dir1.0.join("file3.txt"), dir1.1.join("file3.txt")); let file4 = (sub.0.join("file4.txt"), sub.1.join("file4.txt")); let file5 = (dir2.0.join("file5.txt"), dir2.1.join("file5.txt")); dir::create_all(&dir1.0, true).unwrap(); dir::create_all(&dir1.1, true).unwrap(); dir::create_all(&dir2.0, true).unwrap(); dir::create_all(&dir2.1, true).unwrap(); dir::create_all(&sub.0, true).unwrap(); dir::create_all(&sub.1, true).unwrap(); assert!(&dir1.0.exists()); assert!(&dir1.1.exists()); assert!(&dir2.0.exists()); assert!(&dir2.1.exists()); assert!(&sub.0.exists()); assert!(&sub.1.exists()); fs_extra::file::write_all(&file1.0, "content1").unwrap(); fs_extra::file::write_all(&file2.0, "content2").unwrap(); fs_extra::file::write_all(&file3.0, "content3").unwrap(); fs_extra::file::write_all(&file4.0, "content4").unwrap(); fs_extra::file::write_all(&file5.0, "content5").unwrap(); fs_extra::file::write_all(&file1.1, "old content11").unwrap(); fs_extra::file::write_all(&file2.1, "old content12").unwrap(); fs_extra::file::write_all(&file3.1, "old content13").unwrap(); fs_extra::file::write_all(&file4.1, "old content14").unwrap(); fs_extra::file::write_all(&file5.1, "old content15").unwrap(); assert!(file1.0.exists()); assert!(file2.0.exists()); assert!(file3.0.exists()); assert!(file4.0.exists()); assert!(file5.0.exists()); assert!(file1.1.exists()); assert!(file2.1.exists()); assert!(file3.1.exists()); assert!(file4.1.exists()); assert!(file5.1.exists()); let mut options = dir::CopyOptions::new(); assert!(!compare_dir(&dir1.0, &dir1.1)); assert!(!compare_dir(&dir2.0, &dir2.1)); assert!(!files_eq(&file1.0, &file1.1)); assert!(!files_eq(&file2.0, &file2.1)); options.buffer_size = 1; let (tx, rx) = mpsc::channel(); let result = thread::spawn(move || { let mut count_exist_files = 0; let mut from_paths = Vec::new(); from_paths.push(dir1.0.as_path()); from_paths.push(dir2.0.as_path()); from_paths.push(file1.0.as_path()); from_paths.push(file2.0.as_path()); let result: u64; { let func_test = |process_info: TransitProcess| { let result: dir::TransitProcessResult; match process_info.state { dir::TransitState::Exists => { if count_exist_files == 3 || count_exist_files > 6 { result = dir::TransitProcessResult::Skip; } else { result = dir::TransitProcessResult::Retry; } count_exist_files += 1; tx.send(process_info).unwrap(); } _ => result = dir::TransitProcessResult::Abort, }; result }; result = move_items_with_progress(&from_paths, &path_to, &options, func_test).unwrap(); } assert_eq!(11, count_exist_files); assert_eq!(0, result); assert!(dir1.0.exists()); assert!(dir2.0.exists()); assert!(dir1.1.exists()); assert!(dir2.1.exists()); }).join(); match result { Ok(_) => {} Err(err) => panic!(err), } rx.try_recv().unwrap(); }