use std::collections::HashMap;
use std::env;
use std::fs::*;
use std::io::{BufReader, Read, Write};
use std::path::*;
pub struct EnvCache {
entries: HashMap<String, String>,
}
fn cache_path() -> PathBuf {
Path::new(&env::var("OUT_DIR").unwrap()).join("envcache.config")
}
impl EnvCache {
pub fn new() -> Self {
let cache_path = cache_path();
let mut entries = HashMap::new();
if let Ok(file) = File::open(cache_path) {
let mut f = BufReader::new(file);
let mut string = String::new();
f.read_to_string(&mut string).unwrap();
let mut index = 0;
while index < string.len() {
let env_len = usize::from_str_radix(&string[index..index + 8], 16).unwrap();
index += 8;
let env = &string[index..index + env_len];
index += env_len;
let val_len = usize::from_str_radix(&string[index..index + 8], 16).unwrap();
index += 8;
let val = &string[index..index + val_len];
index += val_len;
entries.insert(env.to_string(), val.to_string());
}
}
Self { entries }
}
pub fn cache<'a>(&'a mut self, env: &str) -> Option<&'a str> {
if let Ok(var) = env::var(env) {
self.entries.insert(env.to_string(), var);
}
if let Some(var) = self.entries.get(&env.to_string()) {
Some(var)
} else {
None
}
}
}
impl Default for EnvCache {
fn default() -> Self {
Self::new()
}
}
impl Drop for EnvCache {
fn drop(&mut self) {
let cache_path = cache_path();
if let Ok(mut file) = File::create(cache_path) {
for (key, val) in self.entries.iter() {
println!("cargo:rerun-if-env-changed={}", key);
println!("cargo:rustc-env={}={}", key, val);
write!(file, "{:08x}{}{:08x}{}", key.len(), key, val.len(), val).unwrap();
}
}
}
}