use crate::files::*;
use crate::generator::Generator;
use serde_derive::Serialize;
use std::collections::HashMap;
use std::io::Read;
use std::io::Write;
#[derive(Serialize)]
pub struct PasswordsFile(HashMap<String, HashMap<String, String>>);
pub struct FileContent {
config_file: fs::File,
password_file: fs::File,
}
impl FileContent {
pub fn default() -> Self {
let paths_list = FilePaths::default();
let config_file = fs::OpenOptions::new()
.read(true)
.write(true)
.open(paths_list.config_path)
.expect("could not open");
let password_file = fs::OpenOptions::new()
.read(true)
.write(true)
.open(paths_list.password_path)
.expect("could not open");
Self {
config_file,
password_file,
}
}
pub fn init_config(mut self) -> Self {
let mut config_content: String = String::new();
self.config_file
.read_to_string(&mut config_content)
.expect("failed to make a string");
if config_content.is_empty() {
let config_struct: Generator = Generator::new(10)
.lowercase(true)
.uppercase(true)
.symbols(true)
.numbers(true)
.begin_with_letter(true)
.category("unknown".to_string());
config_content = toml::to_string(&config_struct).unwrap();
let config_byte_content = config_content.as_bytes();
self.config_file
.write_all(config_byte_content)
.expect("failed to write to file");
}
self
}
pub fn edit_passwords(mut self, category_name: Option<&str>, password_name: String) -> String {
let mut config_content: String = String::new();
let mut passwords_content: String = String::new();
self.config_file
.read_to_string(&mut config_content)
.expect("failed to make a string");
self.password_file
.read_to_string(&mut passwords_content)
.expect("failed to make a string");
let generator: Generator =
toml::from_str(&config_content).expect("failed to generate config");
let password = generator.generate().unwrap();
if passwords_content.is_empty() {
let mut passwords_map: HashMap<String, String> = HashMap::new();
passwords_map.insert(password_name, password);
let mut categories_map: HashMap<String, HashMap<String, String>> = HashMap::new();
if let Some(category_value) = category_name {
categories_map.insert(category_value.to_string(), passwords_map);
} else {
categories_map.insert(generator.category, passwords_map);
}
let file_content = PasswordsFile(categories_map);
toml::to_string_pretty(&file_content).expect("failed to generate string")
} else {
let mut file_content: HashMap<String, HashMap<String, String>> =
toml::from_str(&passwords_content).expect("failed to convert");
if let Some(category_value) = category_name {
if let Some(category_map) = file_content.get_mut(category_value) {
category_map.insert(password_name, password);
} else {
let mut password_map: HashMap<String, String> = HashMap::new();
password_map.insert(password_name, password);
file_content.insert(category_value.to_string(), password_map);
}
} else if let Some(category_map) = file_content.get_mut(&generator.category) {
category_map.insert(password_name, password);
} else {
let mut password_map: HashMap<String, String> = HashMap::new();
password_map.insert(password_name, password);
file_content.insert(generator.category, password_map);
}
toml::to_string_pretty(&file_content).expect("failed to generate string")
}
}
pub fn save_passwords(self, category_name: Option<&str>, password_name: String) {
let path = { FilePaths::default().password_path };
let write = self.edit_passwords(category_name, password_name);
let mut file = fs::OpenOptions::new().write(true).open(path).unwrap();
file.write_all(write.as_bytes()).unwrap();
}
}