use diesel::result::Error; use rocket::http::Status; use rocket::response::status; use rocket_contrib::json::Json; use rocket_contrib::templates::Template; use std::collections::HashMap; use syntect::highlighting::ThemeSet; use syntect::html::highlighted_html_for_string; use syntect::parsing::SyntaxSet; use crate::connection::DbConn; use crate::gists; use crate::gists::{Gist, InsertableGist}; fn error_response(error: Error) -> Status { match error { Error::NotFound => Status::NotFound, _ => Status::InternalServerError, } } fn format_gist(filetype: Option, body: String) -> String { filetype.map_or( format!("
{}
", body), |filetype| { let ps = SyntaxSet::load_defaults_newlines(); let ts = ThemeSet::load_defaults(); ps.find_syntax_by_extension(&filetype).map_or( format!("
{}
", body), |syntax| { highlighted_html_for_string(&body, &ps, syntax, &ts.themes["Solarized (light)"]) }, ) }, ) } #[get("/")] pub fn index(connection: DbConn) -> Result>, Status> { gists::all(&connection) .map(|gists| Json(gists)) .map_err(|error| error_response(error)) } #[get("/gists/")] pub fn show_gist(id: i32, connection: DbConn) -> Template { let result = match gists::get(&connection, id) { Ok(gist) => Some(gist), Err(_) => None, }; let (title, body) = result.map_or( ( String::from("404 - Gist not found"), format!("{}", "Gist not found"), ), |gist| (gist.title, format_gist(gist.filetype, gist.body)), ); let mut context: HashMap<&str, String> = HashMap::new(); context.insert("title", title); context.insert("body", body); Template::render("gists/show", &context) } #[post("/api/gists", format = "application/json", data = "")] pub fn create_gist<'a>( gist: Json, connection: DbConn, ) -> Result>, Status> { gists::insert(gist.into_inner(), &connection) .map(|gist| status::Created(String::from(""), Some(Json(gist)))) .map_err(|error| error_response(error)) }