use std::fmt::Debug;
use std::{env, fs};
use std::env::set_var;
use std::path::PathBuf;
use json::{JsonValue, object};
#[derive(Clone, Debug)]
pub struct Config {
pub root_dir: PathBuf,
pub config_dir: PathBuf,
pub log: bool,
pub extend: Vec<String>,
pub addon_hide: Vec<String>,
pub web_service: bool,
pub db_backup: bool,
pub backup_cycle: bool,
pub backup_regular: bool,
pub cache: bool,
pub token_exp: u64,
pub token: String,
pub pub_key_path: String,
}
impl Config {
pub fn new(path: &str) -> Result<Config, String> {
let dir = env::current_exe().unwrap().parent().map(|x| { x.to_path_buf() }).unwrap();
let t = match dir.file_name().unwrap().to_str().unwrap() {
"debug" => {
dir.join("..").join("..").join(path)
}
"examples" => {
dir.join("..").join(path)
}
_ => {
dir.join(path)
}
};
if !t.is_dir() {
match fs::create_dir_all(&t) {
Ok(_) => {}
Err(e) => {
return Err(format!("配置文件夹不存在: {}", e));
}
}
}
let config_dir = t;
let root_dir = config_dir.parent().unwrap().to_path_buf();
set_var("ROOT_DIR", root_dir.to_str().unwrap());
set_var("CONFIG_DIR", config_dir.to_str().unwrap());
let t = config_dir.join("conf.json");
let json = if !t.is_file() {
Config::create_json_file(t.clone())?
} else {
match fs::read_to_string(t.clone()) {
Ok(e) => match json::parse(&*e) {
Ok(e) => e,
Err(_) => Config::create_json_file(t.clone())?
},
Err(e) => return Err(format!("文件加载失败: {e}"))
}
};
Ok(Config::form(json))
}
fn create_json_file(path_buf: PathBuf) -> Result<JsonValue, String> {
let data = Config::default().json();
match fs::write(path_buf.clone(), data.dump().clone()) {
Ok(_) => {}
Err(e) => {
return Err(format!("文件写入失败: {}", e));
}
}
Ok(data)
}
fn form(json: JsonValue) -> Self {
let default = json["default"].as_str().unwrap_or("");
let json = json["connections"][default].clone();
let root_dir = PathBuf::from(std::env::var("ROOT_DIR").unwrap());
let config_dir = PathBuf::from(std::env::var("CONFIG_DIR").unwrap());
Self {
root_dir,
config_dir,
log: json["log"].as_bool().unwrap_or(true),
extend: json["extend"].members().map(|x| x.to_string()).collect::<Vec<String>>().clone(),
addon_hide: json["addon_hide"].members().map(|x| x.to_string()).collect::<Vec<String>>().clone(),
web_service: json["web_service"].as_bool().unwrap_or(false),
db_backup: json["db_backup"].as_bool().unwrap_or(false),
backup_cycle: json["backup_cycle"].as_bool().unwrap_or(false),
backup_regular: json["backup_regular"].as_bool().unwrap_or(false),
cache: json["cache"].as_bool().unwrap_or(false),
token_exp: json["token_exp"].as_u64().unwrap_or(60 * 60 * 4),
token: json["token"].to_string(),
pub_key_path: json["pub_key_path"].to_string(),
}
}
fn json(self) -> JsonValue {
let default = "temp".to_string();
let mut json_data = object! {
"default":default.clone(),
"connections":object! {}
};
let mut config = object! {};
config["log"] = self.log.into();
config["extend"] = self.extend.into();
config["addon_hide"] = self.addon_hide.into();
config["web_service"] = self.web_service.into();
config["backup_cycle"] = self.backup_cycle.into();
config["db_backup"] = self.db_backup.into();
config["backup_regular"] = self.backup_regular.into();
config["cache"] = self.cache.into();
config["token_exp"] = self.token_exp.into();
json_data["connections"][default] = config.clone();
json_data
}
}
impl Default for Config {
fn default() -> Self {
Self {
root_dir: Default::default(),
config_dir: Default::default(),
log: false,
extend: vec![],
addon_hide: vec![],
web_service: false,
db_backup: false,
backup_cycle: false,
backup_regular: false,
cache: false,
token_exp: 60 * 60 * 24,
token: "".to_string(),
pub_key_path: "".to_string(),
}
}
}