summaryrefslogtreecommitdiff
path: root/src/routes.rs
blob: 9a1e401393db378fd35731caf601efed9b98d35f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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<Vec<String>> {
    read_routes_with_prefix(path, "/")
}

fn read_routes_with_prefix(path: &PathBuf, prefix: &str) -> Result<Vec<String>> {
    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<Vec<String>> {
    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())
    }
}