use crate::Result;
use cocoon::Cocoon;
use std::collections::HashMap;
use std::fs::File;
use std::path::{Path, PathBuf};
pub struct Secrets {
path: PathBuf,
password: String,
data: HashMap<String, String>,
}
impl Secrets {
pub fn new<P: AsRef<Path>>(path: P, password: &str) -> Self {
Secrets {
path: path.as_ref().to_path_buf(),
password: password.to_string(),
data: load(path, password),
}
}
pub fn set(&mut self, name: &str, secret: &str) {
self.data.insert(name.to_string(), secret.to_string());
}
pub fn save(&self) -> Result<()> {
save_data(&self.path, &self.password, &self.data)
}
pub fn get(&self, name: &str) -> Option<&String> {
self.data.get(name)
}
}
fn load<P: AsRef<Path>>(path: P, password: &str) -> HashMap<String, String> {
if path.as_ref().exists() {
let cocoon = Cocoon::new(password.as_bytes());
match File::open(path) {
Ok(mut file) => match cocoon.parse(&mut file) {
Ok(bytes) => match std::str::from_utf8(&bytes) {
Ok(json) => match serde_json::from_str::<HashMap<String, String>>(&json) {
Ok(data) => {
return data;
}
Err(e) => {
println!("{:?}", e);
}
},
Err(e) => {
println!("{:?}", e);
}
},
Err(e) => {
println!("{:?}", e);
}
},
Err(e) => {
println!("{:?}", e);
}
};
}
HashMap::new()
}
fn save_data<P: AsRef<Path>>(
path: P,
password: &str,
data: &HashMap<String, String>,
) -> Result<()> {
let mut file = File::create(path)?;
let json = serde_json::to_string_pretty(data)?;
let cocoon = Cocoon::new(password.as_bytes());
match cocoon.dump(json.into_bytes(), &mut file) {
Ok(_) => {}
Err(e) => {
println!("{:?}", e);
}
}
Ok(())
}