The backend of a gist server written in Rust
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

routes.rs 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. use diesel::result::Error;
  2. use rocket::http::Status;
  3. use rocket::request::Request;
  4. use rocket::response::status;
  5. use rocket_contrib::json::Json;
  6. use rocket_contrib::templates::Template;
  7. use std::collections::HashMap;
  8. use crate::connection::DbConn;
  9. use crate::snippet;
  10. use crate::snippet::{ApiSnippet, Snippet};
  11. fn error_response(error: Error) -> Status {
  12. match error {
  13. Error::NotFound => Status::NotFound,
  14. _ => Status::InternalServerError,
  15. }
  16. }
  17. #[get("/")]
  18. pub fn index() -> Template {
  19. let context: HashMap<&str, String> = HashMap::new();
  20. Template::render("index", &context)
  21. }
  22. #[derive(Serialize, Deserialize)]
  23. struct Context {
  24. snippet: Snippet,
  25. lines: Vec<String>,
  26. }
  27. #[get("/snippets/<uuid>")]
  28. pub fn show_snippet(uuid: String, connection: DbConn) -> Template {
  29. let mut context: HashMap<&str, Context> = HashMap::new();
  30. if let Ok(snippet) = snippet::get(&connection, &uuid) {
  31. let lines: Vec<String> = snippet
  32. .formatted_body
  33. .split('\n')
  34. .collect::<Vec<&str>>()
  35. .iter()
  36. .map(|line| line.to_string())
  37. .collect();
  38. context.insert("context", Context { snippet, lines });
  39. Template::render("snippets/show", &context)
  40. } else {
  41. Template::render("404", &context)
  42. }
  43. }
  44. #[get("/snippets/<uuid>/raw")]
  45. pub fn show_raw_snippet(uuid: String, connection: DbConn) -> String {
  46. match snippet::get(&connection, &uuid) {
  47. Ok(snippet) => htmlescape::decode_html(&snippet.body).expect("Invalid HTML"),
  48. Err(_) => String::from("Snippet not found"),
  49. }
  50. }
  51. #[post("/api/snippets", format = "application/json", data = "<snippet>")]
  52. pub fn create_snippet(
  53. snippet: Json<ApiSnippet>,
  54. connection: DbConn,
  55. ) -> Result<status::Created<Json<Snippet>>, Status> {
  56. snippet::insert(snippet.into_inner(), &connection)
  57. .map(|snippet| status::Created(String::from(""), Some(Json(snippet))))
  58. .map_err(error_response)
  59. }
  60. #[catch(400)]
  61. pub fn bad_request(req: &Request) -> String {
  62. req.headers().get_one("content-length").map_or(
  63. String::from("{\"message\": \"Bad request\"}"),
  64. |length| {
  65. if length
  66. .parse::<i32>()
  67. .expect("Content length is non-numeric")
  68. > 1_000_000
  69. {
  70. String::from("{\"message\": \"Snippet must be under 1mb\"}")
  71. } else {
  72. String::from("{\"message\": \"Bad request\"}")
  73. }
  74. },
  75. )
  76. }
  77. #[catch(404)]
  78. pub fn not_found() -> Template {
  79. let context: HashMap<(), ()> = HashMap::new();
  80. Template::render("404", &context)
  81. }