pkgs/config/
name_package.rs

1use std::collections::BTreeMap;
2
3use super::{Config, PkgsParseError, VarMap, VarsParseError};
4use crate::config::{Package, PackageType};
5
6impl Config {
7    pub fn get(&self, name: &str) -> Result<NamedPackage, PkgsParseError> {
8        Ok(NamedPackage::try_new(
9            name,
10            self.packages[name].clone(),
11            VarMap::try_new(&self.vars)?, // PERF: varmap will be built multiple times here
12        )?)
13    }
14}
15
16#[derive(Debug)]
17pub struct NamedPackage {
18    name: String,
19    kind: PackageType,
20    maps: BTreeMap<String, String>,
21}
22
23impl NamedPackage {
24    pub fn try_new(name: &str, package: Package, vars: VarMap) -> Result<Self, VarsParseError> {
25        let mut maps = BTreeMap::new();
26        for (k, v) in package.maps {
27            maps.insert(k, vars.parse(&v)?);
28        }
29
30        Ok(Self {
31            name: name.to_string(),
32            kind: package.kind,
33            maps,
34        })
35    }
36
37    pub fn get_directory(&self) -> String {
38        match self.kind() {
39            PackageType::Local => self.name.to_string(),
40        }
41    }
42
43    pub fn name(&self) -> &str {
44        &self.name
45    }
46
47    pub fn kind(&self) -> PackageType {
48        self.kind
49    }
50
51    pub fn maps(&self) -> &BTreeMap<String, String> {
52        &self.maps
53    }
54
55    #[cfg(test)]
56    pub fn insert_map(&mut self, key: impl AsRef<str>, value: impl AsRef<str>) {
57        self.maps
58            .insert(key.as_ref().to_string(), value.as_ref().to_string());
59    }
60
61    #[cfg(test)]
62    pub fn remove_map(&mut self, key: impl AsRef<str>) {
63        self.maps.remove(key.as_ref());
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70    use crate::{fs::home_dir, test_utils::prelude::*};
71
72    fn setup() -> Config {
73        let vars = vec![
74            ("APP_DIR".to_string(), "${HOME}/myapp".to_string()),
75            ("MY_VAR1".to_string(), "hello".to_string()),
76            ("MY_VAR2".to_string(), "${MY_VAR1}_world".to_string()),
77        ];
78
79        let packages = BTreeMap::from_iter([(
80            "test_pkg".to_string(),
81            Package {
82                kind: PackageType::Local,
83                maps: BTreeMap::from_iter([
84                    ("app_dir".to_string(), "${APP_DIR}".to_string()),
85                    ("path".to_string(), "/usr/local/${MY_VAR2}".to_string()),
86                    ("config".to_string(), "${MY_VAR1}_config".to_string()),
87                ]),
88            },
89        )]);
90
91        Config { vars, packages }
92    }
93
94    #[gtest]
95    fn it_works() -> Result<()> {
96        let config = setup();
97
98        let pkg = config.get("test_pkg")?;
99        expect_eq!(pkg.name(), "test_pkg");
100        expect_eq!(pkg.kind(), PackageType::Local);
101        expect_eq!(pkg.get_directory(), "test_pkg");
102
103        expect_eq!(pkg.maps().len(), 3);
104        expect_eq!(
105            pkg.maps()["app_dir"],
106            home_dir().join("myapp").to_str().unwrap()
107        );
108        expect_eq!(pkg.maps()["path"], "/usr/local/hello_world");
109        expect_eq!(pkg.maps()["config"], "hello_config");
110
111        Ok(())
112    }
113
114    #[gtest]
115    fn unknown_var_when_build() -> Result<()> {
116        let mut config = setup();
117        config
118            .vars
119            .push(("MY_VAR3".to_string(), "${UNKNOWN}".to_string()));
120
121        let err = config.get("test_pkg").unwrap_err();
122        expect_that!(err, pat!(PkgsParseError::VarsBuild(_)));
123
124        Ok(())
125    }
126
127    #[gtest]
128    fn unknown_var_when_parse() -> Result<()> {
129        let mut config = setup();
130        config
131            .packages
132            .get_mut("test_pkg")
133            .unwrap()
134            .maps
135            .insert("bad".to_string(), "${UNKNOWN}".to_string());
136
137        let err = config.get("test_pkg").unwrap_err();
138        expect_that!(err, pat!(PkgsParseError::VarsParse(_)));
139
140        Ok(())
141    }
142}