The backend of a gist server written in Rust
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.

routes.rs 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. use diesel::result::Error;
  2. use rocket::http::Status;
  3. use rocket::response::status;
  4. use rocket_contrib::json::Json;
  5. use rocket_contrib::templates::Template;
  6. use std::collections::HashMap;
  7. use syntect::highlighting::ThemeSet;
  8. use syntect::html::highlighted_html_for_string;
  9. use syntect::parsing::SyntaxSet;
  10. use crate::connection::DbConn;
  11. use crate::gists;
  12. use crate::gists::{Gist, InsertableGist};
  13. fn error_response(error: Error) -> Status {
  14. match error {
  15. Error::NotFound => Status::NotFound,
  16. _ => Status::InternalServerError,
  17. }
  18. }
  19. fn format_gist(filetype: Option<String>, body: String) -> String {
  20. filetype.map_or(
  21. format!("<pre class='plaintext'>{}</pre>", body),
  22. |filetype| {
  23. let ps = SyntaxSet::load_defaults_newlines();
  24. let ts = ThemeSet::load_defaults();
  25. ps.find_syntax_by_extension(&filetype).map_or(
  26. format!("<pre class='plaintext'>{}</pre>", body),
  27. |syntax| {
  28. highlighted_html_for_string(&body, &ps, syntax, &ts.themes["Solarized (light)"])
  29. },
  30. )
  31. },
  32. )
  33. }
  34. #[get("/")]
  35. pub fn index(connection: DbConn) -> Result<Json<Vec<Gist>>, Status> {
  36. gists::all(&connection)
  37. .map(|gists| Json(gists))
  38. .map_err(|error| error_response(error))
  39. }
  40. #[get("/gists/<id>")]
  41. pub fn show_gist(id: i32, connection: DbConn) -> Template {
  42. let result = match gists::get(&connection, id) {
  43. Ok(gist) => Some(gist),
  44. Err(_) => None,
  45. };
  46. let (title, body) = result.map_or(
  47. (
  48. String::from("404 - Gist not found"),
  49. format!("<h3'>{}</h3>", "Gist not found"),
  50. ),
  51. |gist| (gist.title, format_gist(gist.filetype, gist.body)),
  52. );
  53. let mut context: HashMap<&str, String> = HashMap::new();
  54. context.insert("title", title);
  55. context.insert("body", body);
  56. Template::render("gists/show", &context)
  57. }
  58. #[post("/api/gists", format = "application/json", data = "<gist>")]
  59. pub fn create_gist<'a>(
  60. gist: Json<InsertableGist>,
  61. connection: DbConn,
  62. ) -> Result<status::Created<Json<Gist>>, Status> {
  63. gists::insert(gist.into_inner(), &connection)
  64. .map(|gist| status::Created(String::from(""), Some(Json(gist))))
  65. .map_err(|error| error_response(error))
  66. }