collector/
lib.rs

1use std::collections::HashMap;
2use std::env;
3use std::path::PathBuf;
4
5use anyhow::{Context, Result};
6
7enum Collectible {
8    Project(String),
9    Lang,
10}
11
12fn dirs(c: Collectible) -> Result<Vec<PathBuf>> {
13    let current_dir = env::current_dir()?;
14    let dir = match c {
15        Collectible::Lang => current_dir.join("../langs"),
16        Collectible::Project(lang) => current_dir.join("../langs").join(lang),
17    };
18    let mut entries = vec![];
19
20    for entry in dir
21        .read_dir()
22        .with_context(|| format!("read_dir call failed for dir {}", dir.display()))?
23    {
24        if let Ok(entry) = entry {
25            entries.push(entry.path().to_path_buf())
26        }
27    }
28    Ok(entries)
29}
30
31fn basename(p: PathBuf) -> Result<String> {
32    Ok(p.file_name().unwrap().to_string_lossy().into_owned())
33}
34
35pub fn collect() -> Result<HashMap<String, Vec<PathBuf>>> {
36    let mut map = HashMap::new();
37    let langs = dirs(Collectible::Lang).context("failed to get available languages")?;
38    for lang in langs {
39        let projects = dirs(Collectible::Project(lang.to_str().unwrap().to_string())).with_context(|| {
40            format!(
41                "failed to get available projects for lang {}",
42                &lang.display()
43            )
44        })?;
45        map.insert(basename(lang)?, projects);
46    }
47    Ok(map)
48}