use std::collections::HashMap;
use crate::Parser;
use file_sql::ForceUnwrap;
trait RemoveQuote {
fn remove_quote(self) -> String;
}
impl RemoveQuote for String {
fn remove_quote(self) -> String {
if self.starts_with("\"") && self.ends_with("\"") {
return self[1..self.len() - 1].to_string();
}
self
}
}
#[derive(Debug, Clone)]
pub struct Service {
pub name: String,
pub file: String,
pub url: String,
pub desp: String,
}
impl Service {
pub fn from_map(index: usize, map: &HashMap<String, Option<String>>) -> Self {
let name = map
.get("name")
.and_then(|s| s.clone())
.or(Some(format!("service.{}", index)))
.force_unwrap()
.remove_quote();
let desp = map
.get("desp")
.and_then(|s| s.clone())
.or(Some(format!("no description")))
.force_unwrap()
.remove_quote();
let file = map
.get("file")
.and_then(|s| s.clone())
.force_unwrap()
.remove_quote();
let url = map
.get("url")
.and_then(|s| s.clone())
.force_unwrap()
.remove_quote();
Self {
name,
file,
url,
desp,
}
}
}
#[derive(Debug, Clone)]
pub struct App {
pub dir: String,
pub port: String,
pub path: String,
pub title: String,
pub sub_title: String,
pub table_heads: Vec<String>,
pub services: Vec<Service>,
}
impl App {
pub fn from_file(path: &str) -> Self {
Self::from(Parser::from_file(path))
}
pub fn parse_env() -> Self {
let path = if let Some(input) = std::env::args().nth(1) {
format!("{}/{}", std::env::current_dir().unwrap().display(), input)
} else {
format!("{}/fql.ini", std::env::current_dir().unwrap().display())
};
if !std::path::Path::new(&path).exists() {
println!("Config file [\"{}\"] load failed", path);
std::process::exit(0);
}
Self::from_file(&path)
}
pub fn localhost(&self) -> String {
format!("localhost:{}", self.port)
}
}
impl From<Parser<'_>> for App {
fn from(parser: Parser<'_>) -> Self {
let port = parser
.get_value("main/port", "4000".to_string())
.remove_quote();
let title = parser
.get_value("main/title", "FQLServer".to_string())
.remove_quote();
let sub_title = parser
.get_value("main/subtitle", "welcome to index page".to_string())
.remove_quote();
let mut index = 0;
let mut services = Vec::new();
while let Some(map) = parser.value.get(&format!("service.{}", index)) {
services.push(Service::from_map(index, map));
index += 1;
}
let file = std::path::Path::new(parser.path.unwrap());
let dir = file.parent().unwrap().to_str().unwrap().to_string();
let table_heads = vec![
parser
.get_value("main/name", "Name".to_string())
.remove_quote(),
parser
.get_value("main/url", "URL".to_string())
.remove_quote(),
parser
.get_value("main/desp", "Description".to_string())
.remove_quote(),
parser
.get_value("main/file", "File".to_string())
.remove_quote(),
];
Self {
dir,
title,
sub_title,
table_heads,
port,
services,
path: parser.path.unwrap().to_string(),
}
}
}
#[cfg(test)]
mod test {
use crate::*;
#[test]
fn test_app() {
let app = App::from_file("examples/fql.server.ini");
println!("{:#?}", app);
}
}