32 lines
955 B
Rust
32 lines
955 B
Rust
|
|
use rayon::prelude::*;
|
||
|
|
use std::fs;
|
||
|
|
use std::io;
|
||
|
|
use std::path::Path;
|
||
|
|
use std::os::unix;
|
||
|
|
|
||
|
|
pub fn hardcopy(source: &Path, destination: &Path) -> io::Result<()> {
|
||
|
|
let metadata = fs::symlink_metadata(source)?;
|
||
|
|
|
||
|
|
if metadata.file_type().is_file() {
|
||
|
|
fs::hard_link(source, destination)?;
|
||
|
|
} else if metadata.file_type().is_dir() {
|
||
|
|
fs::create_dir_all(destination)?;
|
||
|
|
|
||
|
|
let entries: Vec<_> = fs::read_dir(source)?.collect::<io::Result<Vec<_>>>()?;
|
||
|
|
entries.par_iter().try_for_each(|entry| {
|
||
|
|
let path = entry.path();
|
||
|
|
if let Some(file_name) = path.file_name() {
|
||
|
|
let dest_path = destination.join(file_name);
|
||
|
|
hardcopy(&path, &dest_path)
|
||
|
|
} else {
|
||
|
|
Ok(())
|
||
|
|
}
|
||
|
|
})?;
|
||
|
|
} else if metadata.file_type().is_symlink() {
|
||
|
|
let target = fs::read_link(source)?;
|
||
|
|
unix::fs::symlink(target, destination)?;
|
||
|
|
}
|
||
|
|
|
||
|
|
Ok(())
|
||
|
|
}
|