use fs_extra::dir::DirContent; pub fn get_dir_content_filtered(p: &std::path::Path, ignored: &Vec) -> Result { let p = p.canonicalize().map_err(|e| e.to_string())?; let base_path_len = p.to_str().unwrap().len() + 1; let retain_fn = |p: &String| { if p.len() < base_path_len { return false; } let rel_path = p.split_at(base_path_len).1; !ignored.iter().any(|i| rel_path.starts_with(i)) }; let mut content = fs_extra::dir::get_dir_content(p).map_err(|e| e.to_string())?; content.files.retain(retain_fn); content.directories.retain(retain_fn); Ok(content) } pub fn trim_dir_content(mut content: DirContent, base: &std::path::Path) -> DirContent { let base_path_len = base.canonicalize().unwrap().to_str().unwrap().len() + 1; let iter_fn = |p: &mut String| { if p.len() < base_path_len { return; } let _ = p.drain(..base_path_len).collect::>(); }; content.files.iter_mut().for_each(iter_fn); content.directories.iter_mut().for_each(iter_fn); content } pub fn copy_dir(src_dir: &std::path::Path, dst_dir: &std::path::Path, spinner: &indicatif::ProgressBar) -> Result<(), String> { let content = src_dir.read_dir().map_err(|e| e.to_string())?; for entry in content { let entry = entry.map_err(|e| e.to_string())?; let new_dst = dst_dir.join(entry.file_name()); if entry.path().is_file() { std::fs::copy(entry.path(), new_dst).map_err(|e| e.to_string())?; spinner.tick(); } else { std::fs::create_dir_all(&new_dst).map_err(|e| e.to_string())?; spinner.tick(); copy_dir(&entry.path(), &new_dst, spinner)?; } } Ok(()) }