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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;

use color_eyre::eyre::Result;
use toml::Table;

use crate::config::Settings;
use crate::default_shorthands::DEFAULT_SHORTHANDS;
use crate::dirs;

pub type Shorthands = HashMap<String, String>;

pub fn get_shorthands(settings: &Settings) -> Shorthands {
    let mut shorthands = HashMap::new();
    if !settings.disable_default_shorthands {
        shorthands.extend(
            DEFAULT_SHORTHANDS
                .iter()
                .map(|(k, v)| (k.to_string(), v.to_string())),
        );
    };
    if let Some(f) = &settings.shorthands_file {
        match parse_shorthands_file(f.clone()) {
            Ok(custom) => {
                shorthands.extend(custom);
            }
            Err(err) => {
                warn!("Failed to read shorthands file: {} {:#}", &f.display(), err);
            }
        }
    }
    shorthands
}

fn parse_shorthands_file(mut f: PathBuf) -> Result<Shorthands> {
    if f.starts_with("~") {
        f = dirs::HOME.join(f.strip_prefix("~")?);
    }
    let raw = fs::read_to_string(&f)?;
    let toml = raw.parse::<Table>()?;

    let mut shorthands = HashMap::new();
    for (k, v) in toml {
        if let Some(v) = v.as_str() {
            shorthands.insert(k, v.to_string());
        }
    }
    Ok(shorthands)
}

#[cfg(test)]
mod tests {
    use pretty_assertions::assert_str_eq;

    use super::*;

    #[test]
    fn test_get_shorthands() {
        let settings = Settings {
            shorthands_file: Some("../fixtures/shorthands.toml".into()),
            ..Settings::default()
        };
        let shorthands = get_shorthands(&settings);
        assert_str_eq!(
            shorthands["elixir"],
            "https://github.com/asdf-vm/asdf-elixir.git"
        );
        assert_str_eq!(shorthands["node"], "https://node");
        assert_str_eq!(shorthands["xxxxxx"], "https://xxxxxx");
    }

    #[test]
    fn test_get_shorthands_missing_file() {
        let settings = Settings {
            shorthands_file: Some("test/fixtures/missing.toml".into()),
            ..Settings::default()
        };
        let shorthands = get_shorthands(&settings);
        assert!(!shorthands.is_empty());
    }
}