1use hyper::service::{make_service_fn, service_fn};
2use hyper::{Body, Request, Response, Server};
3use macroblog::blog::{render_index_page, render_post_page, render_projects};
4use macroblog::router::Router;
5use std::convert::Infallible;
6use std::env;
7use std::net::SocketAddr;
8
9async fn not_found() -> Result<Response<Body>, Infallible> {
10 let resp: Response<Body> = Response::builder()
11 .status(404)
12 .body("Not Found".into())
13 .unwrap();
14 Ok(resp)
15}
16
17async fn index() -> Result<Response<Body>, Infallible> {
18 let body = render_index_page();
19
20 let resp: Response<Body> = Response::builder()
21 .status(200)
22 .header("posts-type", "text/html")
23 .body(body.into())
24 .unwrap();
25
26 Ok(resp)
27}
28
29async fn projects() -> Result<Response<Body>, Infallible> {
30 let body = render_projects();
31
32 let resp: Response<Body> = Response::builder()
33 .status(200)
34 .header("posts-type", "text/html")
35 .body(body.into())
36 .unwrap();
37
38 Ok(resp)
39}
40
41async fn post(path: &String) -> Result<Response<Body>, Infallible> {
42 let body = render_post_page(path);
43
44 let resp: Response<Body> = Response::builder()
45 .status(200)
46 .header("posts-type", "text/html")
47 .body(body.into())
48 .unwrap();
49
50 Ok(resp)
51}
52
53async fn request(req: Request<Body>) -> Result<Response<Body>, Infallible> {
54 let path = req.uri().path();
55
56 match Router::new(path) {
57 Router::Index => index().await,
58 Router::Projects => projects().await,
59 Router::Post { page } => post(&page).await,
60 Router::NotFound => not_found().await,
61 }
62}
63
64#[tokio::main]
65async fn main() {
66 let port = env::var("PORT")
67 .unwrap_or("3000".into())
68 .parse::<u16>()
69 .unwrap_or(3000);
70 let addr = SocketAddr::from(([0, 0, 0, 0], port));
71
72 let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(request)) });
73
74 let server = Server::bind(&addr).serve(make_svc);
75
76 if let Err(e) = server.await {
77 eprintln!("server error: {}", e);
78 }
79}