pub mod router; use std::convert::Infallible; use rust_embed::RustEmbed; use std::{env, str}; use std::net::SocketAddr; use hyper::{Body, Request, Response, Server}; use hyper::service::{make_service_fn, service_fn}; use sailfish::TemplateOnce; use ::router::Router; #[derive(TemplateOnce)] #[template(path = "index.html")] struct IndexTemplate { posts: Vec, } #[derive(TemplateOnce)] #[template(path = "post.html")] struct PostTemplate { content: String, } #[derive(RustEmbed)] #[folder = "content/posts/"] struct PostAsset; fn get_file_content(path: &str) -> String { let buffer = PostAsset::get(path) .unwrap() .data .into_owned(); return String::from_utf8(buffer).unwrap(); } fn get_post_title() -> Vec { PostAsset::iter() .map(|e| format!("{}", e)) .collect() } async fn not_found() -> Result, Infallible> { let resp: Response = Response::builder() .status(404) .body("Not Found".into()) .unwrap(); Ok(resp) } async fn index() -> Result, Infallible> { let files = get_post_title(); let body = IndexTemplate { posts: files } .render_once() .unwrap(); let resp: Response = Response::builder() .status(200) .header("posts-type", "text/html") .body(body.into()) .unwrap(); Ok(resp) } async fn post(path: &String) -> Result, Infallible> { let body = PostTemplate { content: get_file_content(path) } .render_once() .unwrap(); let resp: Response = Response::builder() .status(200) .header("posts-type", "text/html") .body(body.into()) .unwrap(); Ok(resp) } async fn request(req: Request) -> Result, Infallible> { let path = req.uri().path(); match Router::new(path) { Router::Index => index().await, Router::Post { page } => post(&page).await, Router::NotFound => not_found().await } } #[tokio::main] async fn main() { let port = env::var("PORT").unwrap_or("3000".into()).parse::().unwrap_or(3000); let addr = SocketAddr::from(([0, 0, 0, 0], port)); let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(request)) }); let server = Server::bind(&addr).serve(make_svc); if let Err(e) = server.await { eprintln!("server error: {}", e); } }