pub mod db;
pub mod default;
#[cfg(feature = "email")]
pub mod email;
pub mod registry;
#[cfg(feature = "worker")]
pub mod worker;
use crate::error::RoadsterResult;
use async_trait::async_trait;
#[cfg(feature = "open-api")]
use schemars::JsonSchema;
use serde_derive::{Deserialize, Serialize};
use serde_json::Value;
use serde_with::{serde_as, skip_serializing_none};
use std::time::Duration;
use tracing::error;
#[serde_as]
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, bon::Builder)]
#[cfg_attr(feature = "open-api", derive(JsonSchema))]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct CheckResponse {
pub status: Status,
#[builder(with = |duration: std::time::Duration| duration.as_millis())]
pub latency: u128,
#[builder(with = |custom: impl serde::Serialize| serialize_custom(custom))]
pub custom: Option<Value>,
}
fn serialize_custom(custom: impl serde::Serialize) -> Value {
serde_json::to_value(custom)
.unwrap_or_else(|err| Value::String(format!("Unable to serialize custom data: {err}")))
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "open-api", derive(JsonSchema))]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub enum Status {
Ok,
Err(ErrorData),
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, bon::Builder)]
#[cfg_attr(feature = "open-api", derive(JsonSchema))]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct ErrorData {
#[builder(into)]
pub msg: Option<String>,
}
#[cfg_attr(test, mockall::automock)]
#[async_trait]
pub trait HealthCheck: Send + Sync {
fn name(&self) -> String;
fn enabled(&self) -> bool;
async fn check(&self) -> RoadsterResult<CheckResponse>;
}
#[allow(dead_code)]
fn missing_context_response() -> CheckResponse {
let msg = "AppContext missing; is the app shutting down?".to_string();
error!(msg);
CheckResponse::builder()
.status(Status::Err(ErrorData::builder().msg(msg).build()))
.latency(Duration::from_secs(0))
.build()
}
#[cfg(test)]
mod tests {
use insta::assert_json_snapshot;
#[test]
fn missing_context_response() {
assert_json_snapshot!(super::missing_context_response());
}
}