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}