wayver's git archive


a simple self-hosted git server
git clone https://git.wayver.dev/bile

src/http/mod.rs@6e060abc1f25c2e1b79fe06bfa8b72cd26952ee1

raw
Date Commit Message Author Files + -
2026-02-19 17:51 large refactoring wayverd 53 2153 1683
...

1pub(crate) mod extractor;
2pub(crate) mod response;
3
4use std::sync::Arc;
5
6use axum::response::{IntoResponse as _, Response};
7use http::StatusCode;
8use syntect::parsing::SyntaxSet;
9
10use crate::{config::Config, error::Result, http::response::ErrorPage};
11
12#[derive(Clone)]
13pub(crate) struct BileState {
14    pub(crate) config: Arc<Config>,
15    pub(crate) syntax: Arc<SyntaxSet>,
16}
17
18impl BileState {
19    pub(crate) fn new(config: Config, syntax: SyntaxSet) -> Self {
20        Self {
21            config: Arc::new(config),
22            syntax: Arc::new(syntax),
23        }
24    }
25
26    pub(crate) async fn spawn<F>(&self, f: F) -> Response
27    where
28        F: FnOnce(Self) -> Result<Response> + Send + 'static,
29    {
30        let span = tracing::Span::current();
31
32        let this = self.clone();
33
34        spawn_blocking(move || span.in_scope(|| wrap_err(&this.config.clone(), f(this)))).await
35    }
36}
37
38// TODO: https://github.com/rust-lang/rust/issues/110011
39// #[track_caller]
40async fn spawn_blocking<F, R>(f: F) -> R
41where
42    F: FnOnce() -> R + Send + 'static,
43    R: Send + 'static,
44{
45    tokio::task::spawn_blocking(f)
46        .await
47        .expect("failed to join spawn_blocking call, this should only happen due to a panic")
48}
49
50fn wrap_err(config: &Config, res: Result<Response>) -> Response {
51    match res {
52        Ok(res) => res,
53        Err(err) => {
54            tracing::error!(err=?err, "failed to handle response");
55
56            ErrorPage::new(config)
57                .with_status(StatusCode::INTERNAL_SERVER_ERROR)
58                .into_response()
59        }
60    }
61}
62