use std::net::{IpAddr, Ipv4Addr}; use anyhow::Context; use axum_app_wrapper::AdHocPlugin; {% if include_aide %} use schemars::JsonSchema; {% endif %} use serde::Deserialize; use crate::state::AppState; #[derive(Debug, Clone, Deserialize{% if include_aide %}, JsonSchema{% endif %})] pub struct AppConfig { pub api_key: String, #[serde(default = "default_host")] pub host: IpAddr, #[serde(default = "default_port")] pub port: u16, #[serde(default = "default_log_level")] pub log_level: String, } fn default_host() -> IpAddr { IpAddr::V4(Ipv4Addr::LOCALHOST) } fn default_port() -> u16 { {{default_port}} } fn default_log_level() -> String { "{{default_log_level}}".to_string() } /// Plugin that reads and validates configuration, and adds it to server state pub fn plugin() -> AdHocPlugin { AdHocPlugin::new().on_init(|mut state| async move { let config = extract_config()?; state.insert(config); Ok(state) }) } /// Extract the configuration from env variables prefixed with `{{env_prefix}}_`. fn extract_config() -> anyhow::Result { let config = figment::Figment::new() .merge(figment::providers::Env::prefixed("{{env_prefix}}_")) .extract::() .context("Failed to extract valid configuration")?; Ok(config) }