use diesel::result::Error; use rocket::http::Status; use rocket::request::Request; use rocket::response::status; use rocket_contrib::json::Json; use rocket_contrib::templates::Template; use std::collections::HashMap; use crate::connection::DbConn; use crate::snippet; use crate::snippet::{ApiSnippet, Snippet}; fn error_response(error: Error) -> Status { match error { Error::NotFound => Status::NotFound, _ => Status::InternalServerError, } } #[get("/")] pub fn index() -> Template { let context: HashMap<&str, String> = HashMap::new(); Template::render("index", &context) } #[derive(Serialize, Deserialize)] struct Context { snippet: Snippet, lines: Vec, } #[get("/snippets/")] pub fn show_snippet(uuid: String, connection: DbConn) -> Template { let mut context: HashMap<&str, Context> = HashMap::new(); if let Ok(snippet) = snippet::get(&connection, &uuid) { let lines: Vec = snippet .formatted_body .split('\n') .collect::>() .iter() .map(|line| line.to_string()) .collect(); context.insert("context", Context { snippet, lines }); Template::render("snippets/show", &context) } else { Template::render("404", &context) } } #[get("/snippets//raw")] pub fn show_raw_snippet(uuid: String, connection: DbConn) -> String { match snippet::get(&connection, &uuid) { Ok(snippet) => htmlescape::decode_html(&snippet.body).expect("Invalid HTML"), Err(_) => String::from("Snippet not found"), } } #[post("/api/snippets", format = "application/json", data = "")] pub fn create_snippet( snippet: Json, connection: DbConn, ) -> Result>, Status> { snippet::insert(snippet.into_inner(), &connection) .map(|snippet| status::Created(String::from(""), Some(Json(snippet)))) .map_err(error_response) } #[catch(400)] pub fn bad_request(req: &Request) -> String { req.headers().get_one("content-length").map_or( String::from("{\"message\": \"Bad request\"}"), |length| { if length .parse::() .expect("Content length is non-numeric") > 1_000_000 { String::from("{\"message\": \"Snippet must be under 1mb\"}") } else { String::from("{\"message\": \"Bad request\"}") } }, ) } #[catch(404)] pub fn not_found() -> Template { let context: HashMap<(), ()> = HashMap::new(); Template::render("404", &context) }