use std::collections::HashMap; use axum::{extract::State, response::IntoResponse, Json}; use serde::{Deserialize, Serialize}; use crate::{service::Services, Status}; pub mod services; pub fn router() -> axum::Router { use axum::routing::get; axum::Router::new() .route("/healthcheck", get(healthcheck)) .merge(services::router()) } #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct Health { #[serde(flatten)] pub status: Status, pub checks: HashMap, } impl From for Health { fn from(value: T) -> Self { Health { status: value.into(), ..Default::default() } } } impl IntoResponse for Health { fn into_response(self) -> axum::response::Response { Json(self).into_response() } } pub async fn healthcheck(State(services): State) -> Health { let checks = match services.check().await { Ok(c) => c, Err(err) => return err.into(), }; let status = match checks .values() .filter(|s| !matches!(s, Status::Pass)) .count() { 0 => Status::Pass, 1 => Status::Fail(Some("1 issue detected".to_string())), n => Status::Fail(Some(format!("{n} issues detected"))), }; Health { status, checks } }