br-web 0.6.0

This is an WEB SERVER
Documentation
use json::{JsonValue, object};

#[derive(Clone, Debug)]
pub struct Config {
    /// 开启调试
    pub debug: bool,
    /// 服务器地址
    pub url: String,
    /// 服务器 主机 host
    pub host: String,
    /// 服务器 端口 port
    pub port: String,
    /// 对外访问目录
    pub public: String,
    /// 运行目录
    pub runtime: String,
    /// 协议
    pub schema: String,
    /// 安全协议
    pub ssl: bool,
    /// 私钥文件
    pub ssl_pkey: String,
    /// 公钥文件
    pub ssl_certs: String,
    /// 跨域请求配置
    pub cors: Cors,
    /// 日志记录 默认开启
    pub log: bool,
    /// 根目录
    pub root_dir: String,
}

impl Config {
    /// 默认
    pub fn default() -> Self {
        Self {
            url: "".to_string(),
            host: "0.0.0.0".to_string(),
            port: "3535".to_string(),
            public: "public".to_string(),
            runtime: "runtime".to_string(),
            cors: Cors::default(),
            ssl: false,
            ssl_pkey: "".to_string(),
            ssl_certs: "".to_string(),
            debug: false,
            schema: "http".to_string(),
            log: true,
            root_dir: String::new(),
        }
    }
    /// 加载数据
    pub fn from(data: JsonValue) -> Self {
        let schema = if data["ssl"].as_bool().unwrap_or(false) {
            "https"
        } else {
            "http"
        };
        Self {
            host: data["host"].as_str().unwrap_or("").to_string(),
            port: data["port"].to_string(),
            url: "".to_string(),
            public: data["public"].as_str().unwrap_or("public").to_string(),
            runtime: data["runtime"].as_str().unwrap_or("runtime").to_string(),
            cors: Cors::from(data["cors"].clone()),
            ssl: data["ssl"].as_bool().unwrap_or(false),
            ssl_pkey: data["ssl_pkey"].as_str().unwrap_or("").to_string(),
            ssl_certs: data["ssl_certs"].as_str().unwrap_or("").to_string(),
            debug: data["debug"].as_bool().unwrap_or(false),
            schema: schema.to_string(),
            log: data["log"].as_bool().unwrap_or(true),
            root_dir: data["root_dir"].as_str().unwrap_or("").to_string(),
        }
    }
    pub fn json(self) -> JsonValue {
        object! {
            host:self.host,
            port:self.port,
            public:self.public,
            runtime:self.runtime,
            cors:self.cors.json(),
            ssl:self.ssl,
            ssl_pkey:self.ssl_pkey,
            ssl_certs:self.ssl_certs,
            debug:self.debug,
            log:self.log,
        }
    }
}


/// 跨域资源共享
#[derive(Clone, Debug)]
pub struct Cors {
    /// 指定允许访问资源的来源
    pub allow_origin: Vec<String>,
    /// 指定允许的 HTTP 请求方法
    pub allow_methods: String,
    /// 指定允许的请求头
    pub allow_headers: String,
    /// 是否允许发送身份验证凭据(例如,cookies、HTTP 认证)。
    pub allow_credentials: bool,
    /// 跨域请求请求头中允许携带的除Cache-Controller、Content-Language、Content-Type、Expires、Last-Modified、Pragma这六个基本字段之外的其他字段信息
    pub expose_headers: String,
    /// 准备响应前的缓存持续的最大时间(以秒为单位,目的是减少浏览器预检请求/响应交互的数量。默认值1800s。设置了该值后,浏览器将在设置值的时间段内对该跨域请求不再发起预请求
    pub max_age: i32,
}

impl Cors {
    /// 默认
    pub fn default() -> Self {
        Self {
            allow_origin: vec![],
            allow_methods: "GET,POST".to_string(),
            allow_headers: "content-type,X-Requested-With,x-api,x-token,x-mode".to_string(),
            allow_credentials: true,
            expose_headers: "content-disposition".to_string(),
            max_age: 86400,
        }
    }
    /// 转JSONValue
    pub fn json(self) -> JsonValue {
        let res = format!("{:?}", self);
        let res = res.replace("Cors {", "{");
        let res = res.replace(",},", "}");
        let res = res.replace(": ", "\": ");
        let res = res.replace("{ ", "{ \"");
        let res = res.replace(", ", ", \"");
        json::parse(&res).unwrap()
    }
    pub fn from(data: JsonValue) -> Self {
        Self {
            allow_origin: data["allow_origin"].members().map(|x| x.to_string()).collect(),
            allow_methods: data["allow_methods"].to_string(),
            allow_headers: data["allow_headers"].to_string(),
            allow_credentials: data["allow_credentials"].as_bool().unwrap_or(true),
            expose_headers: data["expose_headers"].to_string(),
            max_age: data["max_age"].as_i32().unwrap_or(86400),
        }
    }
}