use std::env;
use file_engine::{FileEngine, Progress};
#[tokio::main]
async fn main() -> file_engine::Result<()> {
let mut args = env::args().skip(1);
let dest = match args.next() {
Some(dest) => dest,
None => {
eprintln!("usage: basic_move_many <dest_dir> <source>...");
std::process::exit(2);
}
};
let sources: Vec<String> = args.collect();
if sources.is_empty() {
eprintln!("usage: basic_move_many <dest_dir> <source>...");
std::process::exit(2);
}
println!("moving {} source(s) into {dest}", sources.len());
let engine = FileEngine::new();
let mut handle = engine
.move_many(sources, &dest)
.overwrite(true)
.start()?;
let mut completed: usize = 0;
while let Some(progress) = tokio_stream::StreamExt::next(handle.progress()).await {
match progress {
Progress::Started {
bytes_total,
entries_total,
} => match bytes_total {
Some(bytes) => println!("started: {entries_total} entries, {bytes} bytes total"),
None => println!("started: {entries_total} entries"),
},
Progress::EntryCompleted { .. } => {
completed += 1;
if completed.is_multiple_of(200) {
println!(
"...{completed} entries done ({:?} elapsed)",
handle.elapsed()
);
}
}
Progress::EntryFailed { entry } => {
eprintln!("FAILED (during move): {}", entry.relative_path.display());
}
_ => {}
}
}
let outcome = handle.await?;
println!();
println!("done in {:?}", outcome.duration);
println!("succeeded: {}", outcome.succeeded.len());
println!("failed: {}", outcome.failed.len());
for (entry, err) in &outcome.failed {
println!(" - {}: {err}", entry.relative_path.display());
}
if !outcome.sources_failed.is_empty() {
println!("sources_failed: {}", outcome.sources_failed.len());
for (path, err) in &outcome.sources_failed {
println!(" - {}: {err}", path.display());
}
}
if !outcome.cleanup_failed.is_empty() {
println!("cleanup_failed: {}", outcome.cleanup_failed.len());
for (entry, err) in &outcome.cleanup_failed {
println!(" - {}: {err}", entry.relative_path.display());
}
}
if let Some(reason) = outcome.stopped_early {
println!("stopped early: {reason:?}");
}
Ok(())
}