1use heck::ToShoutySnakeCase;
6
7use std::collections::HashMap;
8use std::env::vars;
9use std::path::PathBuf;
10
11#[derive(Debug)]
14pub struct CargoEnv {
15 vars: HashMap<String, String>,
16}
17
18impl CargoEnv {
19 pub fn get_entry<S: AsRef<str>>(&self, key: S) -> Option<&str> {
23 let key = key.as_ref().to_shouty_snake_case();
24 println!("key = {:?}", key);
25 self.vars
26 .get(&key)
27 .or_else(|| self.vars.get(&format!("CARGO_{}", key)))
28 .map(|s| s.as_str())
29 }
30
31 pub fn package_name(&self) -> &str {
33 self.get_entry("pkg-name")
34 .expect("Should always be available")
35 }
36
37 pub fn manifest_directory(&self) -> PathBuf {
39 PathBuf::from(
40 self.get_entry("manifest-dir")
41 .expect("Should always be available"),
42 )
43 }
44}
45
46pub fn get_cargo_env() -> Option<CargoEnv> {
48 let vars: HashMap<String, String> = HashMap::from_iter(vars());
49 if vars.contains_key("CARGO") {
50 Some(CargoEnv {
51 vars: vars
52 .into_iter()
53 .filter(|(key, _)| key.starts_with("CARGO") || key == "OUT_DIR")
54 .collect(),
55 })
56 } else {
57 None
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use crate::cargo::get_cargo_env;
64
65 #[test]
66 fn can_get_env() {
67 let _ = get_cargo_env().expect("should be available because running tests through cargo");
68 }
69
70 #[test]
71 fn can_get_pkg_name() {
72 let cargo = get_cargo_env().unwrap();
73 let name = cargo
74 .get_entry("pkg-name")
75 .expect("Failed because CARGO_ wasn't appended");
76 assert_eq!(name, "assemble-core");
77 }
78
79 #[test]
80 fn can_get_manifest_dir() {
81 let cargo = get_cargo_env().unwrap();
82 let dir = cargo.manifest_directory();
83 assert!(dir.ends_with("assemble-core"));
84 }
85}