diff --git a/Cargo.lock b/Cargo.lock index e297745..b24bd01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1026,7 +1026,7 @@ dependencies = [ [[package]] name = "qchgk_web" -version = "0.1.0" +version = "0.1.1" dependencies = [ "ledb", "ledb-derive", diff --git a/Cargo.toml b/Cargo.toml index f945d19..da99446 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "qchgk_web" -version = "0.1.0" +version = "0.1.1" authors = ["Dmitry "] edition = "2021" diff --git a/src/main.rs b/src/main.rs index f104649..584ebc0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,11 +9,6 @@ extern crate serde_json; extern crate ledb_derive; extern crate ledb_types; -//#[macro_use] -//extern crate tera; - -//use tera::Context; - #[macro_use] extern crate rocket; extern crate rocket_contrib; @@ -28,6 +23,18 @@ use rand::Rng; use ledb::{Options, Storage}; +trait ErrorEmpty { + type Output; + fn err_empty(self) -> Result; +} + +impl ErrorEmpty for Result { + type Output = T; + fn err_empty(self) -> Result { + self.map_err(|_| ()) + } +} + #[derive(Debug, Default, Clone, Serialize, Deserialize, Document)] struct BatchInfo { #[document(primary)] @@ -120,66 +127,53 @@ fn random_question_id(database_distribution: &Uniform) -> u32 { rng.sample(database_distribution) } -fn get_question(storage: &Storage, id: u32) -> Result, ()> { - if 0 == id { - return Ok(None); - } - - let collection = storage +fn get_question(storage: &Storage, id: u32) -> Result { + storage .collection("questions") - .expect("collection \"questions\""); - let last_id = collection.last_id().expect("\"questions\" last_id"); - - if id > last_id { - Err(()) - } else { - let question = collection.get::(id); - if question.is_err() { - Err(()) - } else { - Ok(question.unwrap()) - } - } + .err_empty()? + .get::(id) + .err_empty()? + .ok_or(()) } -fn show_question_details( - template_name: &'static str, - data: &AppState, - id: u32, -) -> Result { - let question = get_question(&data.storage, id); - - if question.is_ok() { - let question = question.unwrap(); - - if question.is_some() { - let question = question.unwrap(); +fn show_question_details(template_name: &'static str, data: &AppState, id: u32) -> Template { + match get_question(&data.storage, id) { + Ok(question) => { let mut context = serde_json::to_value(question).expect("question serialize"); if context.is_object() { let next_id = random_question_id(&data.database_distribution); context["next"] = serde_json::to_value(next_id).expect("question id serialize"); } - Ok(Template::render(template_name, &context)) - } else { - Err(Redirect::permanent("/q/")) + Template::render(template_name, &context) + } + Err(_) => { + use std::collections::HashMap; + let context: HashMap = HashMap::new(); + Template::render("404", &context) } - } else { - use std::collections::HashMap; - let context: HashMap = HashMap::new(); - Ok(Template::render("404", &context)) } } #[get("/q/")] -fn show_question(data: State, id: u32) -> Result { +fn show_question(data: State, id: u32) -> Template { show_question_details("question", data.inner(), id) } #[get("/q//a")] -fn show_answer(data: State, id: u32) -> Result { +fn show_answer(data: State, id: u32) -> Template { show_question_details("answer", data.inner(), id) } +#[get("/q/0")] +fn question0() -> Redirect { + Redirect::to("/") +} + +#[get("/q/0/a")] +fn answer0() -> Redirect { + Redirect::to("/") +} + #[get("/")] fn index(data: State) -> Redirect { let id = random_question_id(&data.database_distribution); @@ -211,7 +205,10 @@ fn rocket() -> Rocket { rocket::ignite() .manage(state) .register(catchers![not_found]) - .mount("/", routes![index, show_question, show_answer]) + .mount( + "/", + routes![index, show_question, show_answer, question0, answer0], + ) .mount("/q", routes![index]) .mount("/q/static", StaticFiles::from("static/")) .attach(Template::fairing())