main.rs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #![feature(proc_macro_hygiene, decl_macro)]
  2. #[macro_use] extern crate rocket;
  3. use failure::Error;
  4. use rocket::response::content;
  5. use serde::Serialize;
  6. #[derive(Debug, Serialize)]
  7. struct Todos {
  8. todos: Vec<TodoItem>,
  9. }
  10. #[derive(Debug, Serialize)]
  11. struct TodoItem {
  12. done: bool,
  13. item: String,
  14. }
  15. fn find_all_todos(doc: &two_trucs::parse::Doc, todos: &mut Vec<TodoItem>) -> Result<(), Error> {
  16. use two_trucs::parse::Node;
  17. use two_trucs::render::render_document;
  18. for node in doc.iter() {
  19. if let Node::Node { tag: _, children } = node {
  20. if let Some(Node::TaskListMarker(done)) = children.first() {
  21. let mut item = std::io::Cursor::new(Vec::new());
  22. render_document(&children.iter().cloned().skip(1).collect(), &mut item)?;
  23. todos.push(TodoItem { done: *done, item: String::from_utf8(item.into_inner())? });
  24. }
  25. find_all_todos(children, todos)?;
  26. }
  27. }
  28. Ok(())
  29. }
  30. fn get_todos(path: &std::path::Path) -> Result<Todos, Error> {
  31. use pulldown_cmark::{Options, Parser};
  32. use std::io::Read;
  33. let mut str = String::new();
  34. std::fs::File::open(path)?.read_to_string(&mut str)?;
  35. let doc = two_trucs::parse::DocBuilder::from(
  36. Parser::new_ext(&str, Options::all())).build();
  37. let mut todos = Vec::new();
  38. find_all_todos(&doc, &mut todos)?;
  39. Ok(Todos { todos })
  40. }
  41. #[get("/todo")]
  42. fn todo() -> content::Json<String> {
  43. let todos = get_todos(std::path::Path::new("example.md")).unwrap();
  44. content::Json(serde_json::to_string(&todos).unwrap())
  45. }
  46. #[get("/")]
  47. fn index() -> rocket::response::NamedFile {
  48. rocket::response::NamedFile::open("static/index.html").unwrap()
  49. }
  50. fn main() {
  51. rocket::ignite().mount("/", routes![index, todo]).launch();
  52. }