Skip to content

Commit

Permalink
Add mirror copy feature
Browse files Browse the repository at this point in the history
see #5
  • Loading branch information
iPersona committed Sep 6, 2017
1 parent 7c68bf3 commit fcb8a29
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ Cargo.lock
/tests/temp/dir/*/*
/tests/temp/lib/*/*

.vscode/

48 changes: 38 additions & 10 deletions src/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub struct CopyOptions {
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 mirroring directory structure when copying directory.
pub mirror_copy: bool,
}

impl CopyOptions {
Expand All @@ -30,6 +32,7 @@ impl CopyOptions {
overwrite: false,
skip_exist: false,
buffer_size: 64000, //64kb
mirror_copy: false,
}
}
}
Expand Down Expand Up @@ -463,7 +466,9 @@ pub fn create_all<P>(path: P, erase: bool) -> Result<()>
/// 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)?;
///
Expand Down Expand Up @@ -491,23 +496,45 @@ pub fn copy<P, Q>(from: P, to: Q, options: &CopyOptions) -> Result<u64>
}
let mut to: PathBuf = to.as_ref().to_path_buf();

if let Some(dir_name) = from.components().last() {
to.push(dir_name.as_os_str());
if options.mirror_copy {
if !to.exists() {
create_dir_all(&to)?;
}
} else {
err!("Invalid folder from", ErrorKind::InvalidFolder);
}
if let Some(dir_name) = from.components().last() {
to.push(dir_name.as_os_str());
} else {
err!("Invalid folder from", ErrorKind::InvalidFolder);
}

if !to.exists() {
create(&to, false)?;
if !to.exists() {
create(&to, false)?;
}
}

let mut result: u64 = 0;
for entry in read_dir(from)? {
let entry = entry?;
let path = entry.path();
println!("from-sub: {:?}", path);
if path.is_dir() {
result += copy(path, to.clone(), &options)?;
if options.mirror_copy {
println!("is_dir:{:?}", path);
match path.components().last() {
None => err!("No dir name"),
Some(dir_name) => {
let mut to = to.to_path_buf();
to.push(dir_name.as_os_str());
println!("from: {:?}", path);
println!("to: {:?}", to);
result += copy(path.clone(), to.clone(), &options)?;
},
}
} else {
result += copy(path.clone(), to.clone(), &options)?;
}
} else {
println!("is_file:{:?}", path);
let mut to = to.to_path_buf();
match path.file_name() {
None => err!("No file name"),
Expand All @@ -517,8 +544,9 @@ pub fn copy<P, Q>(from: P, to: Q, options: &CopyOptions) -> Result<u64>
let mut file_options = super::file::CopyOptions::new();
file_options.overwrite = options.overwrite;
file_options.skip_exist = options.skip_exist;
println!("from: {:?}", path);
println!("to: {:?}", to);
result += super::file::copy(&path, to.as_path().clone(), &file_options)?;

}
}
}
Expand Down
76 changes: 76 additions & 0 deletions tests/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1070,8 +1070,84 @@ fn it_copy_with_progress_exist_overwrite_and_skip_exist() {

}

#[test]
fn it_copy_mirror_work() {
let mut path_from = PathBuf::from(TEST_FOLDER);
let test_name = "sub";
path_from.push("it_copy_mirror_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 mut options = CopyOptions::new();
options.mirror_copy = true;
options.overwrite = true;
let result = copy(&path_from, &path_to, &options).unwrap();

assert_eq!(16, result);
assert!(path_to.exists());
assert!(path_from.exists());
assert!(compare_dir_mirror(&path_from, &path_to));
}

fn compare_dir_mirror<P, Q>(path_from: P, path_to: Q) -> bool
where P: AsRef<Path>,
Q: AsRef<Path>
{
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_from.as_ref().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_mirror(path, &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() {
Expand Down

0 comments on commit fcb8a29

Please sign in to comment.