Files
quic_ecs_dt/substrate/src/config.rs
2026-05-13 15:03:23 -04:00

81 lines
2.7 KiB
Rust

use bevy::prelude::Resource;
use figment::Figment;
use figment::providers::{Env, Format, Serialized, Toml};
use serde::{Deserialize, Serialize};
#[derive(Debug, Resource, Serialize, Deserialize)]
pub struct AppConfig {
pub network: QuicConfig,
pub simulation: SimulationConfig,
pub observability: ObservabilityConfig,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SimulationConfig {
pub tick_rate_hz: u32,
pub max_entities: usize,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct QuicConfig {
pub server_port: u16,
pub server_interface: String,
pub server_cert: String,
pub server_key: String,
pub t1_capacity: usize,
pub t2_capacity: usize,
pub t3_capacity: usize,
/// Bench-only knob. When > 0, the substrate spawns a synthetic T3
/// driver that issues toggling Relay commands to every connected device
/// at the configured rate, exercising the real outbound code path.
/// Off by default (0.0) in production. Override via env:
/// `APP_NETWORK__SYNTHETIC_T3_RATE_HZ=100`.
#[serde(default)]
pub synthetic_t3_rate_hz: f64,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ObservabilityConfig {
/// When true, install the Prometheus exporter at startup. Disable for
/// environments where the metrics port collides or scraping is undesired.
pub metrics_enabled: bool,
/// Bind address for the `/metrics` HTTP listener.
pub metrics_listen: String,
}
impl Default for AppConfig {
fn default() -> Self {
Self {
network : QuicConfig {
server_port: 9000,
server_interface: "0.0.0.0".to_string(),
server_cert: "certs/server.crt".to_string(),
server_key: "certs/server.key".to_string(),
t1_capacity: 1024,
t2_capacity: 512,
t3_capacity: 256,
synthetic_t3_rate_hz: 0.0,
},
simulation: SimulationConfig {
tick_rate_hz: 60,
max_entities: 10000,
},
observability: ObservabilityConfig {
metrics_enabled: true,
metrics_listen: "0.0.0.0:9100".to_string(),
},
}
}
}
impl AppConfig {
pub fn load(config_file: &str) -> Result<Self, figment::Error> {
Figment::new()
.merge(Serialized::defaults(Self::default())) // compiled-in defaults
.merge(Toml::file(config_file)) // config file
// env overrides — `__` is the nesting separator so
// `APP_NETWORK__SERVER_PORT=9001` overrides `network.server_port`.
.merge(Env::prefixed("APP_").split("__"))
.extract()
}
}