diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..12c920d --- /dev/null +++ b/src/main.rs @@ -0,0 +1,62 @@ +use std::path::Path; + +use anyhow::Result; +use kdam::tqdm; +use walkdir::WalkDir; + +async fn copy(from: String, to: String) -> std::io::Result<()> { + let from_path = std::path::Path::new(&from); + let to_path = std::path::Path::new(&to); + if from_path.is_dir() { + std::fs::create_dir_all(to)?; + } else if from_path.is_file() { + std::fs::create_dir_all(to_path.parent().unwrap())?; + std::fs::copy(from, to)?; + } + Ok(()) +} + +#[tokio::main] +async fn main() -> Result<()> { + let args: Vec<String> = std::env::args().collect(); + + if args.len() != 3 { + println!("{} <source> <destination>", args.first().unwrap()); + return Ok(()); + } + + let source = Path::new(&args[1]); + let destination = Path::new(&args[2]); + const MAX: usize = 100; + let mut tasks = Vec::new(); + let count = WalkDir::new(source) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|e| e.file_type().is_file()).count(); + + for entry in tqdm!(WalkDir::new(source) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|e| e.file_type().is_file()), total = count) + { + let from = entry.path().to_str().unwrap().to_string(); + let rel = entry.path().strip_prefix(source)?; + + let to = { + let mut target = destination.to_path_buf(); + target.push(rel); + target.to_str().unwrap().to_string() + }; + + tasks.push(tokio::spawn(copy(from, to))); + + if tasks.len() > MAX { + for task in tasks { + task.await.unwrap()? + } + tasks = Vec::new(); + } + } + + Ok(()) +} |