use camino::Utf8Path;
use std::{fs, io};
pub fn find_files_in_dir<F>(
dir: &str, recursive: bool, filter: Option<F>,
) -> io::Result<Vec<String>>
where
F: Fn(&str) -> bool + Clone,
{
let mut files = vec![];
let paths = Utf8Path::read_dir_utf8(dir.into())?;
for path in paths {
let path = path?.path().to_string();
let utf8_path = Utf8Path::new(&path);
if utf8_path.is_dir() && recursive {
files.extend(find_files_in_dir(&path, recursive, filter.clone())?);
} else if utf8_path.is_file() {
if let Some(ref filter) = filter {
if filter(&path) {
files.push(path);
}
} else {
files.push(path);
}
}
}
Ok(files)
}
pub fn find_dirs_in_dir<F>(dir: &str, recursive: bool, filter: Option<F>) -> io::Result<Vec<String>>
where
F: Fn(&str) -> bool + Clone,
{
let mut dirs = vec![];
let paths = Utf8Path::read_dir_utf8(dir.into())?;
for path in paths {
let path = path?.path().to_string();
let utf8_path = Utf8Path::new(&path);
if utf8_path.is_dir() {
if let Some(ref filter) = filter {
if filter(&path) {
dirs.push(path);
if recursive {
dirs.extend(find_dirs_in_dir(dir, recursive, Some(filter))?)
}
}
} else {
dirs.push(path);
}
}
}
Ok(dirs)
}
pub fn copy_files_from_dir<T, F>(
source_dir: &str, destination_dir: &str, recursive: bool, filter: Option<F>,
) -> io::Result<()>
where
F: Fn(&str) -> bool + Clone,
{
let source = Utf8Path::new(source_dir);
let dest = Utf8Path::new(destination_dir);
let files = find_files_in_dir(source_dir, recursive, filter)?;
for file in files {
let destination = dest.join(Utf8Path::new(&file).strip_prefix(source).unwrap());
fs::copy(file, destination)?;
}
Ok(())
}
pub fn move_files_from_dir<T, F>(
source_dir: &str, destination_dir: &str, recursive: bool, filter: Option<F>,
) -> io::Result<()>
where
F: Fn(&str) -> bool + Clone,
{
let source = Utf8Path::new(source_dir);
let dest = Utf8Path::new(destination_dir);
let files = find_files_in_dir(source_dir, recursive, filter)?;
for file in files {
let destination = dest.join(Utf8Path::new(&file).strip_prefix(source).unwrap());
fs::rename(file, destination)?;
}
Ok(())
}