use crate::parse_command_line_args;
use std::fs;
use std::io::Write;
use std::path::Path;
pub fn find(_args: &str, handle: &mut Box<dyn Write>) -> Result<(), Box<dyn std::error::Error>> {
let mut path = String::new();
let mut wanted = String::new();
let mut wanted_arg = false;
let args = parse_command_line_args(_args);
for arg in args {
if arg.chars().next() == Some('-') {
let arg_name = &arg[1..arg.len()];
match arg_name {
"name" => {
wanted_arg = true;
}
_ => continue,
}
} else if wanted_arg {
wanted = arg;
wanted_arg = false;
} else if path.is_empty() {
path = arg.to_string();
}
}
let wanted = if wanted.starts_with("*") {
format!(
"{}$",
wanted
.replace("*", ".*")
.replace(".", "\\.")
.replace("?", ".")
)
} else {
format!("^{}", wanted.replace("*", ".*").replace("?", "."))
};
let path = Path::new(&path);
find_directory(&path, &wanted, handle)?;
Ok(())
}
use regex::Regex;
fn find_directory(
directory: &Path,
wanted: &String,
handle: &mut Box<dyn Write>,
) -> Result<(), Box<dyn std::error::Error>> {
let paths = fs::read_dir(directory);
let re = Regex::new(&wanted)?;
match paths {
Ok(paths) => {
for entry in paths {
let entry = entry?;
let filename_os_str = entry.file_name();
let filename = filename_os_str
.to_str()
.ok_or("Invalid UTF-8 in file name")?;
let path = entry.path();
if path.is_dir() {
find_directory(&path, &wanted, handle)?;
}
if re.is_match(filename) {
writeln!(handle, "{}/{}", directory.display(), filename)?;
}
}
}
Err(error) => {
if error.kind() == std::io::ErrorKind::PermissionDenied {
return Ok(());
}
eprintln!("{:?} {}", directory, error);
return Ok(());
}
};
Ok(())
}