atuin_server/handlers/
mod.rs

1use atuin_common::api::{ErrorResponse, IndexResponse};
2use atuin_server_database::Database;
3use axum::{Json, extract::State, http, response::IntoResponse};
4
5use crate::router::AppState;
6
7pub mod health;
8pub mod history;
9pub mod record;
10pub mod status;
11pub mod user;
12pub mod v0;
13
14const VERSION: &str = env!("CARGO_PKG_VERSION");
15
16pub async fn index<DB: Database>(state: State<AppState<DB>>) -> Json<IndexResponse> {
17    let homage = r#""Through the fathomless deeps of space swims the star turtle Great A'Tuin, bearing on its back the four giant elephants who carry on their shoulders the mass of the Discworld." -- Sir Terry Pratchett"#;
18
19    // Error with a -1 response
20    // It's super unlikely this will happen
21    let count = state.database.total_history().await.unwrap_or(-1);
22
23    let version = state
24        .settings
25        .fake_version
26        .clone()
27        .unwrap_or(VERSION.to_string());
28
29    Json(IndexResponse {
30        homage: homage.to_string(),
31        total_history: count,
32        version,
33    })
34}
35
36impl IntoResponse for ErrorResponseStatus<'_> {
37    fn into_response(self) -> axum::response::Response {
38        (self.status, Json(self.error)).into_response()
39    }
40}
41
42pub struct ErrorResponseStatus<'a> {
43    pub error: ErrorResponse<'a>,
44    pub status: http::StatusCode,
45}
46
47pub trait RespExt<'a> {
48    fn with_status(self, status: http::StatusCode) -> ErrorResponseStatus<'a>;
49    fn reply(reason: &'a str) -> Self;
50}
51
52impl<'a> RespExt<'a> for ErrorResponse<'a> {
53    fn with_status(self, status: http::StatusCode) -> ErrorResponseStatus<'a> {
54        ErrorResponseStatus {
55            error: self,
56            status,
57        }
58    }
59
60    fn reply(reason: &'a str) -> ErrorResponse<'a> {
61        Self {
62            reason: reason.into(),
63        }
64    }
65}