repos
/ repos-rust master

repos-rust

mirror archived upstream

A minimal self-hosted git browser on Rust axum: bare repos rendered as a website with commits, diffs, syntax-highlighted blobs, atom feeds, and clone over HTTPS.

axumdockergitgit-browsergitoxidegixrustself-hosted

1.7 KB · 57 lines · Rust Raw History
 1use axum::{
 2    http::StatusCode,
 3    response::{Html, IntoResponse, Response},
 4};
 5use chrono::Datelike;
 6
 7use crate::templates::RequestCtx;
 8use crate::AppState;
 9
10pub fn render(
11    state: &AppState,
12    template: &str,
13    path: &str,
14    extra: minijinja::Value,
15) -> Response {
16    let tmpl = match state.env.get_template(template) {
17        Ok(t) => t,
18        Err(e) => {
19            tracing::error!("template '{}': {}", template, e);
20            return (StatusCode::INTERNAL_SERVER_ERROR, "template error").into_response();
21        }
22    };
23    let body = tmpl.render(minijinja::context! {
24        request => RequestCtx { path: path.to_string() },
25        now => minijinja::context! { year => chrono::Local::now().year() },
26        site => minijinja::context! {
27            title => &state.config.site_title,
28            tagline => &state.config.site_tagline,
29            clone_base => &state.config.clone_base,
30        },
31        base_url => &state.config.base_url,
32        ..extra
33    });
34    match body {
35        Ok(s) => Html(s).into_response(),
36        Err(e) => {
37            tracing::error!("render '{}': {}", template, e);
38            (StatusCode::INTERNAL_SERVER_ERROR, "render error").into_response()
39        }
40    }
41}
42
43/// Log the underlying reason, then render the themed 404. Used everywhere
44/// instead of returning the raw error string so filesystem paths and gix
45/// internals don't leak into the response.
46pub fn not_found(state: &AppState, name: &str, reason: impl std::fmt::Display) -> Response {
47    tracing::info!("{name}: {reason}");
48    let body = render(
49        state,
50        "not_found.html",
51        &format!("/{name}"),
52        minijinja::context! { name => name },
53    );
54    (StatusCode::NOT_FOUND, body).into_response()
55}
56