use crate::create::create_folder_for_file;
use std::path::Path;
use walkdir::WalkDir;
pub fn copy_file<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
let from = from.as_ref();
let to = to.as_ref();
create_folder_for_file(to);
std::fs::copy(from, to)
.unwrap_or_else(|_| panic!("Failed to copy file from '{from:?}' to '{to:?}'."));
}
pub fn copy_folder<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) {
let from = from.as_ref();
let to = to.as_ref();
for entry in WalkDir::new(from).into_iter().filter_map(Result::ok) {
let entry_path = entry.path();
let destination_path = to.join(entry_path.strip_prefix(from).unwrap());
if entry_path.is_file() {
copy_file(entry_path, &destination_path);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::delete::{delete_file, delete_folder};
use crate::load::load_file_as_string;
use crate::path::to_path_buf;
use crate::save::save_string_to_file;
use crate::test_utils::get_temp_dir_path;
use std::path::Path;
use tempfile::tempdir;
#[test]
fn test_copy_file() {
let temp_dir = tempdir().unwrap();
let source_path = get_temp_dir_path(&temp_dir).join("source.txt");
let source_paths: Vec<Box<dyn AsRef<Path>>> = vec![
Box::new(source_path.to_str().unwrap()), Box::new(source_path.to_str().unwrap().to_string()), Box::new(source_path.as_path()), Box::new(source_path.clone()), ];
let destination_path = get_temp_dir_path(&temp_dir).join("destination.txt");
let destination_paths: Vec<Box<dyn AsRef<Path>>> = vec![
Box::new(destination_path.clone()), Box::new(destination_path.as_path()), Box::new(destination_path.to_str().unwrap().to_string()), Box::new(destination_path.to_str().unwrap()), ];
save_string_to_file("Hello, world!", &source_path);
for (source_path, destination_path) in source_paths.iter().zip(destination_paths) {
let source_path: &dyn AsRef<Path> = source_path.as_ref();
let destination_path: &dyn AsRef<Path> = destination_path.as_ref();
assert!(!to_path_buf(destination_path).exists());
copy_file(source_path, destination_path);
assert!(to_path_buf(destination_path).exists());
assert_eq!(load_file_as_string(destination_path), "Hello, world!");
delete_file(destination_path);
assert!(!to_path_buf(destination_path).exists());
}
}
#[test]
fn test_copy_file_with_existing_destination() {
let temp_dir = tempdir().unwrap();
let source_path = get_temp_dir_path(&temp_dir).join("source.txt");
save_string_to_file("Hello, world!", &source_path);
let destination_path = get_temp_dir_path(&temp_dir).join("destination.txt");
save_string_to_file("Old content", &destination_path);
copy_file(&source_path, &destination_path);
assert_eq!(load_file_as_string(&destination_path), "Hello, world!");
}
#[test]
fn test_copy_folder_flat() {
let temp_dir = tempdir().unwrap();
let source_path = get_temp_dir_path(&temp_dir).join("source_folder");
let source_paths: Vec<Box<dyn AsRef<Path>>> = vec![
Box::new(source_path.to_str().unwrap()), Box::new(source_path.to_str().unwrap().to_string()), Box::new(source_path.as_path()), Box::new(source_path.clone()), ];
let destination_path = get_temp_dir_path(&temp_dir).join("destination_folder");
let destination_paths: Vec<Box<dyn AsRef<Path>>> = vec![
Box::new(destination_path.clone()), Box::new(destination_path.as_path()), Box::new(destination_path.to_str().unwrap().to_string()), Box::new(destination_path.to_str().unwrap()), ];
let source_path = get_temp_dir_path(&temp_dir).join("source_folder");
save_string_to_file("Hello, world!", source_path.join("file_1.txt"));
save_string_to_file("hello world", source_path.join("file_2.txt"));
for (source_path, destination_path) in source_paths.iter().zip(destination_paths) {
let source_path: &dyn AsRef<Path> = source_path.as_ref();
let destination_path: &dyn AsRef<Path> = destination_path.as_ref();
assert!(!to_path_buf(destination_path).exists());
copy_folder(source_path, destination_path);
assert!(to_path_buf(destination_path).exists());
assert_eq!(
load_file_as_string(to_path_buf(destination_path).join("file_1.txt")),
"Hello, world!"
);
assert_eq!(
load_file_as_string(to_path_buf(destination_path).join("file_2.txt")),
"hello world"
);
delete_folder(destination_path);
assert!(!to_path_buf(destination_path).exists());
}
}
#[test]
fn test_copy_folder_nested() {
let temp_dir = tempdir().unwrap();
let source_folder = get_temp_dir_path(&temp_dir).join("source_folder");
save_string_to_file("Hello, world!", source_folder.join("file.txt"));
save_string_to_file(
"Hello from subfolder!",
source_folder.join("subfolder/subfile.txt"),
);
let destination_folder = get_temp_dir_path(&temp_dir).join("destination_folder");
copy_folder(&source_folder, &destination_folder);
assert_eq!(
load_file_as_string(destination_folder.join("file.txt")),
"Hello, world!"
);
assert_eq!(
load_file_as_string(destination_folder.join("subfolder/subfile.txt")),
"Hello from subfolder!"
);
}
#[test]
fn test_copy_folder_with_existing_destination() {
let temp_dir = tempdir().unwrap();
let source_folder = get_temp_dir_path(&temp_dir).join("source_folder");
save_string_to_file("Hello, world!", source_folder.join("file.txt"));
save_string_to_file(
"Overwrite existing file",
source_folder.join("existing_file.txt"),
);
save_string_to_file(
"Hello from subfolder!",
source_folder.join("subfolder/subfile.txt"),
);
let destination_folder = get_temp_dir_path(&temp_dir).join("destination_folder");
save_string_to_file(
"Existing file",
destination_folder.join("existing_file.txt"),
);
copy_folder(&source_folder, &destination_folder);
assert_eq!(
load_file_as_string(destination_folder.join("file.txt")),
"Hello, world!"
);
assert_eq!(
load_file_as_string(destination_folder.join("existing_file.txt")),
"Overwrite existing file"
);
assert_eq!(
load_file_as_string(destination_folder.join("subfolder/subfile.txt")),
"Hello from subfolder!"
);
}
}