1
0
Fork 0
website/src/handlers/mod.rs

70 lines
2 KiB
Rust
Raw Normal View History

2022-08-31 23:20:59 +02:00
use std::sync::Arc;
use serde_derive::Serialize;
use tracing::log::*;
use axum::{response::{Html, IntoResponse, Response}, extract::Path, Extension};
use pulldown_cmark::{Options, Parser, html};
use crate::State;
pub enum Error {
NotFound,
}
pub type Result<T = Html<Vec<u8>>> = std::result::Result<T, Error>;
#[derive(Serialize)]
struct PageContext {
content: String
}
pub async fn index(Extension(state): Extension<Arc<State>>) -> Result {
let ctx = tera::Context::new();
let res = state.tera.render("index.html", &ctx).map_err(|e| { error!("Failed rendering index: {}", e); Error::NotFound})?;
Ok(Html(res.into()))
}
pub async fn post_view(Path(name): Path<String>, Extension(state): Extension<Arc<State>>) -> Result {
info!("Requested post: {}", name);
let state = state.clone();
let post = state.posts.iter().find(|p| p.name == name).ok_or(Error::NotFound)?;
let options = Options::all();
let parser = Parser::new_ext(&post.content, options);
let mut out = String::new();
html::push_html(&mut out, parser);
let ctx = tera::Context::from_serialize(PageContext {
content: out
}).map_err(|_| Error::NotFound)?;
let res = state.tera.render("post.html", &ctx).map_err(|e| { error!("Failed rendering post: {}", e); Error::NotFound})?;
Ok(Html(res.into()))
}
pub async fn post_index(Extension(state): Extension<Arc<State>>) -> Result {
let mut ctx = tera::Context::new();
ctx.insert("posts", &state.posts);
let res = state.tera.render("postsindex.html", &ctx).map_err(|e| { error!("Failed rendering posts index: {}", e); Error::NotFound})?;
Ok(Html(res.into()))
}
impl IntoResponse for Error {
fn into_response(self) -> Response {
let result: Vec<u8> = "not found".into();
let body = axum::body::boxed(axum::body::Full::from(result));
match self {
Error::NotFound => {
Response::builder()
.status(404)
.body(body)
.unwrap()
},
}
}
}