use json::{object, JsonValue};
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Config {
pub debug: bool,
pub host: String,
pub https: bool,
pub tls: TlsConfig,
pub log: bool,
pub root_path: PathBuf,
pub public: String,
pub webpage: String,
pub runtime: String,
pub charset: String,
pub token: String,
pub pub_key_path: String,
#[serde(default = "default_max_body_size")]
pub max_body_size: usize,
#[serde(default = "default_read_timeout")]
pub read_timeout: u64,
#[serde(default = "default_write_timeout")]
pub write_timeout: u64,
#[serde(default = "default_max_connections")]
pub max_connections: usize,
}
fn default_max_body_size() -> usize {
10 * 1024 * 1024
}
fn default_read_timeout() -> u64 {
30
}
fn default_write_timeout() -> u64 {
30
}
fn default_max_connections() -> usize {
1024
}
impl Config {
#[must_use]
pub fn default(path: PathBuf) -> Self {
Self {
debug: true,
host: "0.0.0.0:3535".to_string(),
https: false,
tls: TlsConfig::new(),
log: true,
root_path: path,
public: "public".to_string(),
webpage: "spa".to_string(),
runtime: "runtime".to_string(),
charset: "utf-8".to_string(),
token: String::new(),
pub_key_path: String::new(),
max_body_size: default_max_body_size(),
read_timeout: default_read_timeout(),
write_timeout: default_write_timeout(),
max_connections: default_max_connections(),
}
}
#[must_use]
pub fn create(config_file: &Path, pkg_name: bool) -> Config {
let dir = config_file.parent().unwrap_or(Path::new(".")).to_path_buf();
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ConfigPkg {
pub br_web_server: Config,
}
impl ConfigPkg {
pub fn new(dir: PathBuf) -> ConfigPkg {
Self {
br_web_server: Config::default(dir),
}
}
}
let mut data = Config::default(dir.clone());
data.from();
match fs::read_to_string(config_file) {
Ok(e) => {
if pkg_name {
match toml::from_str::<ConfigPkg>(&e) {
Ok(cfg) => cfg.br_web_server,
Err(_) => Config::default(dir),
}
} else {
data
}
}
Err(_) => {
if pkg_name {
let data = ConfigPkg::new(dir);
let _ = fs::create_dir_all(config_file.parent().unwrap_or(Path::new(".")));
if let Ok(toml) = toml::to_string(&data) {
let _ = fs::write(config_file.to_str().unwrap_or(""), toml);
}
data.br_web_server
} else {
let data = Config::default(dir);
let _ = fs::create_dir_all(config_file.parent().unwrap_or(Path::new(".")));
if let Ok(toml) = toml::to_string(&data) {
let _ = fs::write(config_file.to_str().unwrap_or(""), toml);
}
data
}
}
}
}
fn from(&mut self) -> &mut Config {
let root = self.root_path.clone();
let runtime = root
.join(self.runtime.clone())
.to_str()
.unwrap_or("")
.to_string();
let public = root
.join(self.public.clone())
.to_str()
.unwrap_or("")
.to_string();
let webpage = root.join("webpage").to_str().unwrap_or("").to_string();
let ssl = root.join("ssl").to_str().unwrap_or("").to_string();
let _ = fs::create_dir_all(ssl.clone());
let _ = fs::create_dir_all(runtime.clone());
let _ = fs::create_dir_all(public.clone());
let _ = fs::create_dir_all(webpage.clone());
self
}
#[must_use]
pub fn json(&self) -> JsonValue {
object! {
debug: self.debug,
log: self.log,
host: self.host.as_str(),
https: self.https,
root_path:self.root_path.to_str().unwrap_or(""),
public: self.public.as_str(),
webpage: self.webpage.as_str(),
runtime: self.runtime.as_str(),
charset: self.charset.as_str(),
token: self.token.as_str(),
pub_key_path: self.pub_key_path.as_str(),
max_body_size: self.max_body_size,
read_timeout: self.read_timeout,
write_timeout: self.write_timeout,
max_connections: self.max_connections,
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct TlsConfig {
pub certs: PathBuf,
pub key: PathBuf,
}
impl TlsConfig {
fn new() -> Self {
Self {
certs: PathBuf::default(),
key: PathBuf::default(),
}
}
pub fn json(&self) -> JsonValue {
object! {
certs:self.certs.to_str().unwrap_or(""),
key: self.key.to_str().unwrap_or(""),
}
}
#[must_use]
pub fn from(value: &JsonValue, root: &Path) -> Self {
Self {
certs: root.join(value["certs"].as_str().unwrap_or("")),
key: root.join(value["key"].as_str().unwrap_or("")),
}
}
}