aboutsummaryrefslogtreecommitdiff
path: root/src/handlers/api.rs
blob: af94f6839fcc8c200cf4acfbf7b6409112c1d345 (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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use crate::{
    app::{config::Author, PronounSet, State},
    handlers::Result,
    post::Post,
};
use axum::extract::{Extension, Json, Path};
use lazy_static::lazy_static;
use prometheus::{opts, register_int_counter_vec, IntCounterVec};
use std::{collections::HashMap, sync::Arc};

lazy_static! {
    static ref BLOG: IntCounterVec = register_int_counter_vec!(
        opts!("blogpost_json_hits", "Number of hits to blogposts"),
        &["name"]
    )
    .unwrap();
    static ref TALK: IntCounterVec = register_int_counter_vec!(
        opts!("talks_json_hits", "Number of hits to talks images"),
        &["name"]
    )
    .unwrap();
}

#[axum_macros::debug_handler]
#[instrument(skip(state))]
pub async fn authors(Extension(state): Extension<Arc<State>>) -> Json<HashMap<String, Author>> {
    super::HIT_COUNTER
        .with_label_values(&["authors_json"])
        .inc();
    let state = state.clone();
    let cfg = state.cfg.clone();

    Json(cfg.authors.clone())
}

#[axum_macros::debug_handler]
#[instrument(skip(state))]
pub async fn pronouns(Extension(state): Extension<Arc<State>>) -> Json<Vec<PronounSet>> {
    super::HIT_COUNTER
        .with_label_values(&["pronouns_json"])
        .inc();
    let state = state.clone();
    let cfg = state.cfg.clone();

    Json(cfg.pronouns.clone())
}

#[instrument(skip(state))]
pub async fn blog(
    Path(name): Path<String>,
    Extension(state): Extension<Arc<State>>,
) -> Result<Json<xe_jsonfeed::Item>> {
    let mut want: Option<Post> = None;
    let want_link = format!("blog/{}", name);

    for post in &state.blog {
        if post.link == want_link {
            want = Some(post.clone());
        }
    }

    match want {
        None => Err(super::Error::PostNotFound(name)),
        Some(post) => {
            BLOG.with_label_values(&[name.clone().as_str()]).inc();
            Ok(Json(post.into()))
        }
    }
}

#[instrument(skip(state))]
pub async fn talk(
    Path(name): Path<String>,
    Extension(state): Extension<Arc<State>>,
) -> Result<Json<xe_jsonfeed::Item>> {
    let mut want: Option<Post> = None;
    let want_link = format!("talks/{}", name);

    for post in &state.talks {
        if post.link == want_link {
            want = Some(post.clone());
        }
    }

    match want {
        None => Err(super::Error::PostNotFound(name)),
        Some(post) => {
            TALK.with_label_values(&[name.clone().as_str()]).inc();
            Ok(Json(post.into()))
        }
    }
}