summaryrefslogtreecommitdiff
path: root/src/blog/mod.rs
blob: 23f07218dc67c5004e3fa521ee1901e1c898439a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
pub mod atom;
pub mod helper;

use self::helper::{article_metadata, get_articles};
use crate::error::MyResult;
use crate::layout::{DynScaffold, Scaffold};
use crate::uri;
use anyhow::anyhow;
pub use atom::r_blog_atom;
use atom::rocket_uri_macro_r_blog_atom;
use rocket::{get, response::Redirect};
use std::{path::PathBuf, str::FromStr};
use tokio::fs::read_to_string;

pub const ARTICLE_ROOT: &'static str = "./blog/articles";

#[get("/blog")]
pub fn r_blog() -> Redirect {
    Redirect::to(rocket::uri!(r_blog_index()))
}

#[get("/blog/index")]
pub async fn r_blog_index() -> MyResult<DynScaffold<'static>> {
    // TODO this is a major performance issue here. requires O(n) syscalls to complete
    let articles = get_articles(&PathBuf::from_str(ARTICLE_ROOT).unwrap()).await?;
    Ok(Scaffold {
        title: "blog index".to_string(),
        content: markup::new! {
            h2 { "The Weblog" }
            p { i { "Articles in reverse-chronological order." } }
            p { a[href=uri!(r_blog_atom())]{ "Atom feed" } }
            ul {
                @for a in &articles {
                    li {
                        @a.date.to_string() ": "
                        a[href=uri!(r_blog_article(&a.canonical_name))] { @a.title }
                    }
                }
            }
        },
    })
}

#[get("/blog/<name>")]
pub async fn r_blog_article(name: &str) -> MyResult<DynScaffold<'static>> {
    let apath = PathBuf::from_str(ARTICLE_ROOT)
        .unwrap()
        .join(PathBuf::new().with_file_name(name).with_extension("md"));
    let a = article_metadata(apath.clone()).await?;
    let text = read_to_string(apath).await?;
    let html = markdown::to_html_with_options(
        &text,
        &markdown::Options {
            parse: markdown::ParseOptions {
                constructs: markdown::Constructs {
                    math_flow: true,
                    math_text: true,
                    ..Default::default()
                },
                ..Default::default()
            },
            compile: markdown::CompileOptions {
                ..Default::default()
            },
        },
    )
    .map_err(|e| anyhow!("the server had trouble compiling markdown: {e}"))?;
    Ok(Scaffold {
        title: a.title,
        content: markup::new! {
            @markup::raw(&html)
        },
    })
}