use std::env::consts::OS;
use std::io;
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
use std::sync::mpsc::Sender;
pub fn send_message<T: ToString>(sender: &Sender<T>, message: T) {
match sender.send(message) {
Ok(_) => (),
Err(e) => println!("Message passing error!: {}", e),
}
}
pub fn try_send_message<T: ToString>(sender: &Option<Sender<T>>, message: T) {
match sender {
Some(s) => send_message(s, message),
None => (),
}
}
pub fn get_dir_list<O: AsRef<Path>>(root: O) -> io::Result<Vec<PathBuf>> {
let cur_list: Vec<PathBuf> = root
.as_ref()
.read_dir()?
.map(|entry| entry.unwrap().path())
.collect();
let dir_list = cur_list
.iter()
.filter(|p| p.is_dir())
.map(|p| PathBuf::from(p.to_path_buf()))
.collect::<Vec<_>>();
Ok(dir_list)
}
pub fn get_dir_list_with_depth<O: AsRef<Path>>(root: O, depth: u32) -> io::Result<Vec<PathBuf>> {
if depth == 0 {
return Ok(vec![root.as_ref().to_path_buf()]);
}
let depth = depth - 1;
let mut result = Vec::new();
let cur_list = root
.as_ref()
.read_dir()?
.map(|entry| entry.unwrap().path())
.collect::<Vec<_>>();
let dir_list = cur_list
.iter()
.filter(|p| p.is_dir())
.map(|p| p.to_path_buf())
.collect::<Vec<_>>();
if depth == 0 {
for dir in dir_list {
result.push(dir);
}
} else {
for dir in dir_list {
result.append(&mut get_dir_list_with_depth(dir, depth)?);
}
}
return Ok(result);
}
pub fn get_file_list<O: AsRef<Path>>(root: O) -> io::Result<Vec<PathBuf>> {
let mut file_list: Vec<PathBuf> = Vec::new();
let mut file_queue: Vec<PathBuf> = root
.as_ref()
.read_dir()?
.map(|entry| entry.unwrap().path())
.collect();
let mut i = 0;
loop {
if i >= file_queue.len() {
break;
}
if file_queue[i].is_dir() {
for component in file_queue[i].read_dir()? {
file_queue.push(component.unwrap().path());
}
} else if file_queue[i]
.file_name()
.unwrap()
.to_str()
.unwrap()
.ne(".DS_Store")
{
file_list.push(file_queue[i].to_path_buf());
}
i += 1;
}
Ok(file_list)
}
pub fn get_7z_executable_path() -> Result<PathBuf, io::Error> {
match OS {
"macos" => Ok(PathBuf::from("./7zz")),
"windows" => Ok(PathBuf::from("7z.exe")),
"linux" => Ok(PathBuf::from("./7zzs")),
e => {
println!("Doesn't support {} currently!", e);
return Err(io::Error::new(
ErrorKind::NotFound,
"Cannot find the 7z executable!",
));
}
}
}
#[cfg(test)]
mod tests {
use std::fs;
use super::*;
#[test]
fn get_7z_executable_path_test() {
assert!(get_7z_executable_path().unwrap().is_file());
}
#[test]
fn get_dir_list_with_depth_test() {
fs::create_dir_all("dir_test/dir1/dir2/dir3").unwrap();
assert_eq!(
vec![PathBuf::from("dir_test")],
get_dir_list_with_depth("dir_test", 0).unwrap()
);
assert_eq!(
vec![PathBuf::from("dir_test/dir1")],
get_dir_list_with_depth("dir_test", 1).unwrap()
);
assert_eq!(
vec![PathBuf::from("dir_test/dir1/dir2")],
get_dir_list_with_depth("dir_test", 2).unwrap()
);
assert_eq!(
vec![PathBuf::from("dir_test/dir1/dir2/dir3")],
get_dir_list_with_depth("dir_test", 3).unwrap()
);
assert!(get_dir_list_with_depth("dir_test", 4).unwrap().is_empty());
fs::remove_dir_all("dir_test").unwrap();
}
#[test]
fn get_file_list_test() {
let file_list = get_file_list("original_images").unwrap();
let mut file_list: Vec<&str> = file_list.iter().map(|p| p.to_str().unwrap()).collect();
file_list.sort();
let mut expected_file_list = vec![
"original_images/dir3/file1.png",
"original_images/dir3/file2.jpg",
"original_images/dir1/file3.png",
"original_images/dir3/file4.jpg",
"original_images/dir1/file5.webp",
"original_images/dir2/file6.webp",
"original_images/dir3/file7.txt",
];
expected_file_list.sort();
assert_eq!(file_list, expected_file_list);
}
}