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
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(()) }