123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- use std::fs::File;
- use std::io::prelude::*;
- use std::io::{Error, ErrorKind};
- use std::path::PathBuf;
-
- use dotenv;
- use serde::{Deserialize, Serialize};
- use serde_json;
- use tera::Context;
- use tide::utils::After;
- use tide::{Response, StatusCode};
-
- mod fs;
- mod routes;
-
- #[derive(Debug, Serialize, Deserialize)]
- pub struct Post {
- id: String,
- title: String,
- body: String,
- date: String,
- }
-
- impl Post {
- async fn save(&mut self) -> std::io::Result<()> {
- let mut path: PathBuf = fs::get_posts_directory_path().await?;
- let filename = format!("{}.json", self.id);
- path = path.join(&filename);
- let mut file = File::create(&path)?;
- file.write_all(serde_json::to_string(&self)?.as_bytes())?;
- Ok(())
- }
-
- fn from_str(blob: &str) -> Result<Post, Error> {
- let mut post: Post = match serde_json::from_str(blob) {
- Ok(p) => Ok(p),
- Err(_) => Err(Error::new(
- ErrorKind::Other,
- format!("Error deserializing post"),
- )),
- }?;
- post.body = post.body.replace("\n", "<br>");
- Ok(post)
- }
- }
-
- #[async_std::main]
- async fn main() -> std::io::Result<()> {
- dotenv::dotenv().ok();
- tide::log::start();
- let mut app = tide::new();
-
- app.with(After(|mut res: Response| async {
- let mut context = Context::new();
-
- match res.downcast_error::<async_std::io::Error>() {
- Some(e) => {
- context.insert("error", &e.to_string());
- let status = if let ErrorKind::NotFound = e.kind() {
- StatusCode::NotFound
- } else {
- StatusCode::InternalServerError
- };
- res.set_body(routes::render_template("error.html", &context)?);
- res.set_status(status);
- }
- None => match res.status() {
- StatusCode::NotFound => {
- context.insert("error", "Page not found");
- res.set_body(routes::render_template("error.html", &context)?);
- }
- _ => {}
- },
- };
-
- Ok(res)
- }));
-
- app.with(After(|mut res: Response| async {
- res.set_content_type(tide::http::mime::HTML);
- Ok(res)
- }));
-
- app.with(tide::sessions::SessionMiddleware::new(
- tide::sessions::MemoryStore::new(),
- std::env::var("TIDE_SECRET")
- .expect(
- "Please provide a TIDE_SECRET value of at \
- least 32 bytes in order to run this example",
- )
- .as_bytes(),
- ));
-
- app.at("/").get(routes::index);
- app.at("/posts").post(routes::create_post);
- app.at("/posts/:id").get(routes::single_post);
- app.at("/posts/:id/edit").get(routes::edit_post);
- app.at("/login").get(routes::login_page).post(routes::login);
- app.at("/logout").post(routes::logout);
-
- app.listen("127.0.0.1:8080").await?;
-
- Ok(())
- }
|