mod app;
mod parser;
pub mod tools;
use std::collections::HashMap;
pub use app::*;
pub use parser::Parser;
#[macro_use]
extern crate serde;
#[macro_use]
extern crate nickel;
use nickel::{status::StatusCode, HttpRouter, QueryString};
use file_sql::{AppData, Editor, FQLType, Reader, ForceUnwrap};
use tools::provide_welcome_html;
#[derive(Debug, Serialize)]
pub struct JsonRes<T> {
msg: String,
data: T,
}
impl<T> JsonRes<T> {
pub fn new(data: T) -> Self {
Self {
msg: "success".to_string(),
data,
}
}
pub fn msg<U: std::fmt::Display>(mut self, msg: U) -> Self {
self.msg = format!("{}", msg);
self
}
}
pub fn curd_implement(app: &crate::App, server: &mut nickel::Nickel) {
let html = provide_welcome_html(&app);
server.get("/", middleware!(format!("{}", html)));
for service in &app.services {
let root_file = format!("{}/{}", app.dir, &service.file);
let file = root_file.clone();
let url = service.url.clone();
server.get(
url.clone(),
middleware! { |request|
let mut query = HashMap::new();
let mut msg = String::from("success");
let mut res = file_sql::App::from_file(&file).force_unwrap();
let keys = res.keys.clone();
for key in keys {
if let Some(param) = request.query().get(&key) {
query.insert(key.to_string(), param.to_string());
res = file_sql::App::from(res.find_all(key, FQLType::from(param)));
}
}
if res.data.len() == 0 {
msg = String::from("no result");
}
if let Some(param) = request.query().get("$index") {
query.insert("$index".to_string(), param.to_string());
res = file_sql::App::from(res.find_all("$index", FQLType::from(param)));
if res.data.len() == 0 {
msg = String::from("invalid index");
}
}
println!("GET[\"{}\"]: {:?}", url, query);
let json = JsonRes::new(res.serialize()).msg(msg);
serde_json::to_value(json).map_err(|e| (StatusCode::InternalServerError, e))
},
);
let file = root_file.clone();
let url = service.url.clone();
server.post(
url.clone(),
middleware! { |request|
let mut msg = String::from("success");
let mut query: HashMap<String, FQLType> = HashMap::new();
let mut res = file_sql::App::from_file(&file).force_unwrap();
let keys = res.keys.clone();
for key in &keys {
query.insert(key.to_string(), request.query().get(key).map_or(FQLType::Null, |v| FQLType::from(v)));
}
let new_data = AppData::from(query);
let json = JsonRes::new(new_data.serialize());
println!("POST[\"{}\"]: {:?}", url, new_data.serialize());
if let Some(param) = request.query().get("$index") {
if let Some(index) = res.find_index("$index", FQLType::from(param)) {
res.replace(index, new_data);
msg = format!("replace data at index {}", index);
}
} else {
res.add(new_data);
msg = format!("add data at index {}", res.data.len());
}
res.save_at(&file);
serde_json::to_value(json.msg(msg)).map_err(|e| (StatusCode::InternalServerError, e))
},
);
let file = root_file.clone();
let url = service.url.clone();
server.delete(
url.clone(),
middleware! { |request|
let mut msg = String::new();
let mut query: HashMap<String, String> = HashMap::new();
let mut res = file_sql::App::from_file(&file).force_unwrap();
if let Some(param) = request.query().get("$index") {
query.insert("$index".to_string(), param.to_string());
if let Some(index) = res.find_index("$index", FQLType::from(param)) {
res.remove(index);
msg = format!("remove data at index {}", index);
} else {
msg = String::from("invalid index");
}
} else {
msg = String::from("missing index");
}
res.save_at(&file);
println!("DELETE[\"{}\"]: {:?}", url, query);
serde_json::to_value(JsonRes::new(query).msg(msg)).map_err(|e| (StatusCode::InternalServerError, e))
},
);
}
}