use anyhow::anyhow; use anyhow::Result; use is_executable::is_executable; use std::fs::DirEntry; use std::fs::metadata; use std::{fs::read_dir, path::PathBuf}; pub fn read_routes(path: &PathBuf) -> Result> { read_routes_with_prefix(path, "/") } fn read_routes_with_prefix(path: &PathBuf, prefix: &str) -> Result> { Ok( read_dir(path)? .map(|entry| read_entry_with_prefix(&entry?, path, prefix)) .flatten().flatten().collect()) } fn read_entry_with_prefix(entry: &DirEntry, dir_path: &PathBuf, prefix: &str) -> Result> { let entry_path = entry.path(); let metadata = metadata(&entry_path)?; if metadata.is_dir() { let entry_basename = entry_path.file_name() .ok_or(anyhow!("No basename for file: {:?} in directory: {:?}", entry_path, dir_path))?; let result = read_routes_with_prefix(&entry_path, &format!("{prefix}{:?}/", entry_basename)); result } else if metadata.is_file() { if !is_executable(entry.path()) { eprintln!("Found {:?} in routes config directory, but cannot configure route as the file is not executable", entry); return Ok(Vec::new()); } Ok(vec![format!("{:?}", entry_path)]) } else { eprintln!("Found {:?} in routes config directory, but cannot configure route as the file is neither a directory nor an ordinary file", entry); Ok(Vec::new()) } }