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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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>,

    /// WEB页面服务
    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,
    /// pem路径
    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(),
        }
    }
}