use std::fs;
use std::path::PathBuf;
use serde::Serialize;
use serde::de::DeserializeOwned;
use crate::Error;
const CONFIG_FILE_NAME: &str = "config.toml";
const CONFIG_FILE_PASSWORD: &str = "nupwuz-toxvif-0timNo";
const CONFIG_FILE_NONCE: &str = "novel-rs-config";
pub(crate) fn load_config_file<T, R>(app_name: T) -> Result<Option<R>, Error>
where
T: AsRef<str>,
R: DeserializeOwned,
{
let config_file_path = config_file_path(app_name)?;
if config_file_path.try_exists()? {
tracing::info!(
"The config file is located at: `{}`",
config_file_path.display()
);
if let Ok(config) =
crate::decrypt_from_file(config_file_path, CONFIG_FILE_PASSWORD, CONFIG_FILE_NONCE)
{
if let Ok::<R, _>(config) = toml::from_str(&config) {
Ok(Some(config))
} else {
tracing::error!("Fail to parse the config file, a new one will be created");
Ok(None)
}
} else {
tracing::error!("Fail to decrypt the config file, a new one will be created");
Ok(None)
}
} else {
fs::create_dir_all(config_file_path.parent().unwrap())?;
tracing::info!(
"The config file will be created at: `{}`",
config_file_path.display()
);
Ok(None)
}
}
pub(crate) fn save_config_file<T, E>(app_name: T, config: E) -> Result<(), Error>
where
T: AsRef<str>,
E: Serialize,
{
let config_file_path = config_file_path(app_name)?;
tracing::info!("Save the config file at: `{}`", config_file_path.display());
crate::encrypt_and_save_to_file(
toml::to_string(&config)?,
config_file_path,
CONFIG_FILE_PASSWORD,
CONFIG_FILE_NONCE,
)?;
Ok(())
}
fn config_file_path<T>(app_name: T) -> Result<PathBuf, Error>
where
T: AsRef<str>,
{
let mut config_file_path = crate::config_dir_path(app_name.as_ref())?;
config_file_path.push(CONFIG_FILE_NAME);
Ok(config_file_path)
}