You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.5 KiB
104 lines
2.5 KiB
#![feature(proc_macro_hygiene, decl_macro)]
|
|
|
|
#[macro_use] extern crate rocket;
|
|
#[macro_use] extern crate serde;
|
|
|
|
use serde_json::{json, Value};
|
|
|
|
//use rocket::request::FromSegments;
|
|
//use rocket::http::uri::Segments;
|
|
use rocket_contrib::serve::StaticFiles;
|
|
use rocket_contrib::templates::Template;
|
|
|
|
mod store;
|
|
use crate::store::Store;
|
|
use rocket::State;
|
|
use parking_lot::RwLock;
|
|
use rocket::response::Redirect;
|
|
use rocket::http::Status;
|
|
use rocket::request::Form;
|
|
use std::collections::HashMap;
|
|
use std::env;
|
|
use crate::store::form::RenderedField;
|
|
|
|
fn render_empty_fields<'a>(store : &'a Store) -> Vec<RenderedField<'a>> {
|
|
let indexes = &store.index;
|
|
|
|
store.model.fields.iter().map(|(key, field)| {
|
|
RenderedField::from_template_field(key, field, None, indexes)
|
|
}).collect()
|
|
}
|
|
|
|
#[derive(Serialize,Debug)]
|
|
struct RenderedCard<'a> {
|
|
pub fields : Vec<RenderedField<'a>>,
|
|
pub id : usize,
|
|
}
|
|
|
|
fn render_card_fields<'a>(store : &'a Store, values : &'a serde_json::Map<String, Value>) -> Vec<RenderedField<'a>> {
|
|
let indexes = &store.index;
|
|
|
|
store.model.fields.iter().map(|(key, field)| {
|
|
RenderedField::from_template_field(key, field, values.get(key), indexes)
|
|
}).collect()
|
|
}
|
|
|
|
#[derive(Serialize,Debug)]
|
|
struct ListContext<'a> {
|
|
pub fields : Vec<RenderedField<'a>>,
|
|
pub cards : Vec<RenderedCard<'a>>,
|
|
}
|
|
|
|
#[get("/")]
|
|
fn index(store : State<RwLock<Store>>) -> Template {
|
|
|
|
let rg = store.read();
|
|
|
|
let context = ListContext {
|
|
fields: render_empty_fields(&rg),
|
|
cards: rg.items.iter().filter_map(|(id, card)| {
|
|
if let Value::Object(map) = card {
|
|
Some(RenderedCard {
|
|
fields: render_card_fields(&rg, map),
|
|
id: *id,
|
|
})
|
|
} else {
|
|
None
|
|
}
|
|
}).collect(),
|
|
};
|
|
|
|
Template::render("index", context)
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
struct AddCardContext<'a> {
|
|
pub fields : Vec<RenderedField<'a>>,
|
|
}
|
|
|
|
#[get("/add")]
|
|
fn add(store : State<RwLock<Store>>) -> Template {
|
|
|
|
let rg = store.read();
|
|
|
|
let context = AddCardContext {
|
|
fields: render_empty_fields(&rg)
|
|
};
|
|
|
|
Template::render("add", context)
|
|
}
|
|
|
|
fn main() {
|
|
let cwd = env::current_dir().unwrap();
|
|
let data_dir = cwd.join("data");
|
|
let store = Store::new(data_dir);
|
|
|
|
rocket::ignite()
|
|
.attach(Template::fairing())
|
|
.manage(RwLock::new(store))
|
|
.mount("/", StaticFiles::from(cwd.join("templates/static/")))
|
|
.mount("/", routes![
|
|
index,
|
|
add,
|
|
]).launch();
|
|
}
|
|
|