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.

snippet.rs 2.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. use chrono::NaiveDateTime;
  2. use diesel::pg::PgConnection as PGC;
  3. use diesel::prelude::*;
  4. use syntect::highlighting::ThemeSet;
  5. use syntect::html::highlighted_html_for_string;
  6. use syntect::parsing::SyntaxSet;
  7. use crate::schema::snippets;
  8. #[derive(Queryable, Serialize, Deserialize)]
  9. pub struct Snippet {
  10. pub id: i32,
  11. pub title: String,
  12. pub body: String,
  13. pub created_at: Option<NaiveDateTime>,
  14. pub filetype: Option<String>,
  15. pub formatted_body: String,
  16. }
  17. #[derive(Insertable, AsChangeset, Serialize, Deserialize)]
  18. #[table_name = "snippets"]
  19. pub struct InsertableSnippet {
  20. pub title: String,
  21. pub body: String,
  22. pub filetype: Option<String>,
  23. pub formatted_body: String,
  24. }
  25. fn format_snippet(filetype: Option<String>, body: String) -> String {
  26. filetype.map_or(
  27. format!("<pre class='plaintext'>{}</pre>", body),
  28. |filetype| {
  29. let ps = SyntaxSet::load_defaults_newlines();
  30. let ts = ThemeSet::load_defaults();
  31. ps.find_syntax_by_extension(&filetype).map_or(
  32. format!("<pre class='plaintext'>{}</pre>", body),
  33. |syntax| {
  34. highlighted_html_for_string(
  35. &htmlescape::decode_html(&body).expect("Invalid HTML"),
  36. &ps,
  37. syntax,
  38. &ts.themes["Solarized (light)"],
  39. )
  40. },
  41. )
  42. },
  43. )
  44. }
  45. pub fn get(connection: &PGC, id: i32) -> QueryResult<Snippet> {
  46. snippets::table.find(id).get_result::<Snippet>(connection)
  47. }
  48. pub fn insert(snippet: InsertableSnippet, connection: &PGC) -> QueryResult<Snippet> {
  49. let body = htmlescape::encode_minimal(&snippet.body.clone());
  50. let formatted_snippet = InsertableSnippet {
  51. filetype: snippet.filetype.clone(),
  52. title: snippet.title,
  53. body: body.clone(),
  54. formatted_body: format_snippet(snippet.filetype, body),
  55. };
  56. diesel::insert_into(snippets::table)
  57. .values(formatted_snippet)
  58. .get_result(connection)
  59. }