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
157
158
159
use std::fmt::Debug;
use std::fs;
use json::{JsonValue, object};

/// 框架配置
#[derive(Clone, Debug)]
pub struct Config {
    /// 启用日志
    pub log: bool,
    /// 启动扩展列表
    pub extend: Vec<String>,
    /// 隐藏插件列表
    pub addon_hide: Vec<String>,
    /// 开启wss请求
    pub wss: bool,
    /// 开启http请求
    pub web: bool,
    /// 缓存启动
    pub cache: bool,
    /// 密钥失效时间
    pub token_exp: u64,
    /// 服务器令牌
    pub token: String,
    /// 证书路径
    pub pub_key_path: String,
    /// 分析系统
    pub analysis: Vec<String>,
    /// APP可用插件
    pub app_addon: Vec<String>,
    /// 运行目录
    pub root_path: String,
    /// 数据库同步配置
    pub db_sync: DbSync,

}

impl Config {
    pub fn load(path: &str) -> Self {
        let json = match fs::read_to_string(path) {
            Ok(e) => json::parse(&*e).unwrap(),
            Err(_) => {
                let json = object! {
                    "default":"base",
                    "connections":object! {
                        "base": Config::default().json()
                    }
                };
                fs::write(path, json.to_string()).unwrap();
                json
            }
        };
        Config::from(json)
    }
    pub fn from(data: JsonValue) -> Self {
        let default = data["default"].as_str().unwrap();
        let connection = data["connections"][default].clone();
        let addon_hide = connection["addon_hide"].members().map(|x| x.to_string()).collect::<Vec<String>>().clone();
        Config {
            log: connection["log"].as_bool().unwrap_or(true),
            extend: connection["extend"].members().map(|x| x.to_string()).collect::<Vec<String>>().clone(),
            addon_hide,
            wss: connection["wss"].as_bool().unwrap_or(false),
            web: connection["web"].as_bool().unwrap_or(false),
            cache: connection["cache"].as_bool().unwrap_or(false),
            token_exp: connection["token_exp"].as_u64().unwrap_or(60 * 60 * 4),
            token: connection["token"].to_string(),
            pub_key_path: connection["pub_key_path"].to_string(),
            analysis: connection["analysis"].members().map(|x| x.to_string()).collect::<Vec<String>>().clone(),
            app_addon: connection["app_addon"].members().map(|x| x.to_string()).collect::<Vec<String>>().clone(),
            root_path: connection["root_path"].as_str().unwrap_or("").to_string(),
            db_sync: DbSync::from(connection["db_sync"].clone()),
        }
    }
    pub fn default() -> Self {
        Config {
            log: true,
            extend: vec![],
            addon_hide: vec![],
            wss: false,
            web: false,
            cache: false,
            token_exp: 60 * 60 * 4,
            token: "".to_string(),
            pub_key_path: "".to_string(),
            analysis: vec![],
            app_addon: vec![],
            root_path: "".to_string(),
            db_sync: DbSync::default(),
        }
    }
    pub fn json(self) -> JsonValue {
        let res = format!("{:?}", self);
        let res = res.replace("Config {", "{");
        let res = res.replace("DbSync {", "{");
        let res = res.replace("Master", format!("\"{}\"", self.db_sync.mode.str()).as_str());
        let res = res.replace(",},", "}");
        let res = res.replace(": ", "\": ");
        let res = res.replace("{ ", "{ \"");
        let res = res.replace(", ", ", \"");
        json::parse(&*res).unwrap()
    }
}


/// 数据库同步配置
#[derive(Clone, Debug)]
pub struct DbSync {
    /// 当前模式
    pub mode: SyncMode,
    /// 主机为监听主机地址
    pub host: String,
    /// 从机IP列表
    pub slave: Vec<String>,
    /// 数据库路径
    pub database: String,
}

impl DbSync {
    pub fn default() -> Self {
        Self {
            database: String::new(),
            mode: SyncMode::Master,
            host: String::new(),
            slave: vec![],
        }
    }
    pub fn from(data: JsonValue) -> Self {
        Self {
            mode: SyncMode::from(data["mode"].as_str().unwrap_or("")),
            host: data["host"].as_str().unwrap_or("").to_string(),
            slave: data["slave"].members().map(|x| x.to_string()).collect::<Vec<String>>(),
            database: data["database"].as_str().unwrap_or("").to_string(),
        }
    }
}

#[derive(Clone, Debug)]
pub enum SyncMode {
    /// 主机
    Master,
    /// 从机
    Slave,
}

impl SyncMode {
    pub fn str(&self) -> &'static str {
        match self {
            SyncMode::Master => "master",
            SyncMode::Slave => "slave"
        }
    }
    pub fn from(name: &str) -> Self {
        match name {
            "master" => SyncMode::Master,
            "slave" => SyncMode::Slave,
            _ => SyncMode::Master,
        }
    }
}