1pub mod router;
2
3use std::convert::Infallible;
4use rust_embed::RustEmbed;
5use std::{env, str};
6use std::net::SocketAddr;
7use hyper::{Body, Request, Response, Server};
8use hyper::service::{make_service_fn, service_fn};
9use sailfish::TemplateOnce;
10use ::router::Router;
11
12#[derive(TemplateOnce)]
13#[template(path = "index.html")]
14struct IndexTemplate {
15 posts: Vec<String>,
16}
17
18#[derive(TemplateOnce)]
19#[template(path = "post.html")]
20struct PostTemplate {
21 content: String,
22}
23
24#[derive(RustEmbed)]
25#[folder = "content/posts/"]
26struct PostAsset;
27
28
29fn get_file_content(path: &str) -> String {
30 let buffer = PostAsset::get(path)
31 .unwrap()
32 .data
33 .into_owned();
34
35 return String::from_utf8(buffer).unwrap();
36}
37
38fn get_post_title() -> Vec<String> {
39 PostAsset::iter()
40 .map(|e| format!("{}", e))
41 .collect()
42}
43
44
45async fn not_found() -> Result<Response<Body>, Infallible> {
46 let resp: Response<Body> = Response::builder()
47 .status(404)
48 .body("Not Found".into())
49 .unwrap();
50 Ok(resp)
51}
52
53
54async fn index() -> Result<Response<Body>, Infallible> {
55 let files = get_post_title();
56 let body = IndexTemplate { posts: files }
57 .render_once()
58 .unwrap();
59
60 let resp: Response<Body> = Response::builder()
61 .status(200)
62 .header("posts-type", "text/html")
63 .body(body.into())
64 .unwrap();
65
66 Ok(resp)
67}
68
69
70async fn post(path: &String) -> Result<Response<Body>, Infallible> {
71 let body = PostTemplate { content: get_file_content(path) }
72 .render_once()
73 .unwrap();
74
75 let resp: Response<Body> = Response::builder()
76 .status(200)
77 .header("posts-type", "text/html")
78 .body(body.into())
79 .unwrap();
80
81 Ok(resp)
82}
83
84async fn request(req: Request<Body>) -> Result<Response<Body>, Infallible> {
85 let path = req.uri().path();
86
87 match Router::new(path) {
88 Router::Index => index().await,
89 Router::Post { page } => post(&page).await,
90 Router::NotFound => not_found().await
91 }
92}
93
94
95#[tokio::main]
96async fn main() {
97 let port = env::var("PORT").unwrap_or("3000".into()).parse::<u16>().unwrap_or(3000);
98 let addr = SocketAddr::from(([0, 0, 0, 0], port));
99
100 let make_svc = make_service_fn(|_conn| async {
101 Ok::<_, Infallible>(service_fn(request))
102 });
103
104 let server = Server::bind(&addr).serve(make_svc);
105
106 if let Err(e) = server.await {
107 eprintln!("server error: {}", e);
108 }
109}