use crate::common::config_file::{Settings, SocketSetting};
pub(super) fn apply_env(settings: &mut Settings, warnings: &mut Vec<String>) {
apply_env_general(settings, warnings);
apply_env_local(settings);
apply_env_view(settings);
apply_env_api(settings);
apply_env_alerts(settings);
apply_env_energy(settings);
apply_env_display(settings);
apply_env_record(settings, warnings);
apply_env_snapshot(settings, warnings);
}
fn apply_env_general(settings: &mut Settings, warnings: &mut Vec<String>) {
use std::env;
if let Ok(v) = env::var("ALL_SMI_GENERAL_DEFAULT_MODE") {
match v.as_str() {
"local" | "view" | "api" => settings.general.default_mode = v,
other => warnings.push(format!(
"env ALL_SMI_GENERAL_DEFAULT_MODE: ignored invalid value `{other}`"
)),
}
}
if let Ok(v) = env::var("ALL_SMI_GENERAL_THEME") {
match v.as_str() {
"auto" | "light" | "dark" | "high-contrast" | "mono" => settings.general.theme = v,
other => warnings.push(format!(
"env ALL_SMI_GENERAL_THEME: ignored invalid value `{other}`"
)),
}
}
if let Ok(v) = env::var("ALL_SMI_GENERAL_LOCALE") {
settings.general.locale = v;
}
}
fn apply_env_local(settings: &mut Settings) {
use std::env;
if let Ok(v) = env::var("ALL_SMI_LOCAL_INTERVAL_SECS")
&& let Ok(n) = v.parse::<u64>()
{
settings.local.interval_secs = Some(n);
}
}
fn apply_env_view(settings: &mut Settings) {
use std::env;
if let Ok(v) = env::var("ALL_SMI_VIEW_HOSTFILE")
&& !v.trim().is_empty()
{
settings.view.hostfile = Some(v);
}
if let Ok(v) = env::var("ALL_SMI_VIEW_HOSTS")
&& !v.trim().is_empty()
{
settings.view.hosts = v
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect();
}
if let Ok(v) = env::var("ALL_SMI_VIEW_INTERVAL_SECS")
&& let Ok(n) = v.parse::<u64>()
{
settings.view.interval_secs = Some(n);
}
}
fn apply_env_api(settings: &mut Settings) {
use std::env;
if let Ok(v) = env::var("ALL_SMI_API_PORT")
&& let Ok(n) = v.parse::<u16>()
{
settings.api.port = n;
}
if let Ok(v) = env::var("ALL_SMI_API_SOCKET") {
if v.eq_ignore_ascii_case("false") || v == "0" {
settings.api.socket = SocketSetting::Bool(false);
} else if v.eq_ignore_ascii_case("true") || v == "1" {
settings.api.socket = SocketSetting::Bool(true);
} else {
settings.api.socket = SocketSetting::Path(v);
}
}
if let Ok(v) = env::var("ALL_SMI_API_PROCESSES") {
settings.api.processes = matches!(v.as_str(), "1" | "true" | "TRUE" | "True");
}
if let Ok(v) = env::var("ALL_SMI_API_INTERVAL_SECS")
&& let Ok(n) = v.parse::<u64>()
{
settings.api.interval_secs = n;
}
}
fn apply_env_alerts(settings: &mut Settings) {
use std::env;
if let Ok(v) = env::var("ALL_SMI_ALERT_TEMP")
&& let Ok(n) = v.parse::<u32>()
{
settings.alerts.temp_warn_c = n;
if settings.alerts.temp_crit_c < n + 5 {
settings.alerts.temp_crit_c = n + 10;
}
}
if let Ok(v) = env::var("ALL_SMI_ALERT_UTIL_LOW_MINS")
&& let Ok(n) = v.parse::<u32>()
{
settings.alerts.util_idle_warn_mins = n;
}
if let Ok(v) = env::var("ALL_SMI_ALERTS_TEMP_WARN_C")
&& let Ok(n) = v.parse::<u32>()
{
settings.alerts.temp_warn_c = n;
}
if let Ok(v) = env::var("ALL_SMI_ALERTS_TEMP_CRIT_C")
&& let Ok(n) = v.parse::<u32>()
{
settings.alerts.temp_crit_c = n;
}
if let Ok(v) = env::var("ALL_SMI_ALERTS_UTIL_IDLE_PCT")
&& let Ok(n) = v.parse::<u32>()
{
settings.alerts.util_idle_pct = n;
}
if let Ok(v) = env::var("ALL_SMI_ALERTS_UTIL_IDLE_WARN_MINS")
&& let Ok(n) = v.parse::<u32>()
{
settings.alerts.util_idle_warn_mins = n;
}
if let Ok(v) = env::var("ALL_SMI_ALERTS_HYSTERESIS_C")
&& let Ok(n) = v.parse::<u32>()
{
settings.alerts.hysteresis_c = n;
}
if let Ok(v) = env::var("ALL_SMI_ALERTS_BELL_ON_CRITICAL") {
settings.alerts.bell_on_critical = matches!(v.as_str(), "1" | "true" | "TRUE" | "True");
}
if let Ok(v) = env::var("ALL_SMI_ALERTS_WEBHOOK_URL") {
settings.alerts.webhook_url = v;
}
if let Ok(v) = env::var("ALL_SMI_ALERTS_POWER_CRIT_W")
&& let Ok(n) = v.parse::<u32>()
{
settings.alerts.power_crit_w = n;
}
}
fn apply_env_energy(settings: &mut Settings) {
use std::env;
settings.energy = settings.energy.clone().with_env_overrides();
if let Ok(v) = env::var("ALL_SMI_ENERGY_PRICE_PER_KWH")
&& let Ok(p) = v.parse::<f64>()
&& p.is_finite()
&& p >= 0.0
{
settings.energy.price_per_kwh = p;
}
if let Ok(v) = env::var("ALL_SMI_ENERGY_SHOW_COST") {
settings.energy.show_cost = matches!(v.as_str(), "1" | "true" | "TRUE" | "True");
}
if let Ok(v) = env::var("ALL_SMI_ENERGY_WAL_ENABLED") {
settings.energy.wal_enabled = matches!(v.as_str(), "1" | "true" | "TRUE" | "True");
}
if let Ok(v) = env::var("ALL_SMI_ENERGY_GAP_INTERPOLATE_SECONDS")
&& let Ok(n) = v.parse::<u64>()
&& (1..=3600).contains(&n)
{
settings.energy.gap_interpolate_seconds = n;
}
}
fn apply_env_display(settings: &mut Settings) {
use std::env;
if let Ok(v) = env::var("ALL_SMI_DISPLAY_COLOR_SCHEME") {
settings.display.color_scheme = v;
}
if let Ok(v) = env::var("ALL_SMI_DISPLAY_GAUGE_STYLE") {
settings.display.gauge_style = v;
}
if let Ok(v) = env::var("ALL_SMI_DISPLAY_SHOW_LED_GRID") {
settings.display.show_led_grid = matches!(v.as_str(), "1" | "true" | "TRUE" | "True");
}
}
fn apply_env_record(settings: &mut Settings, warnings: &mut Vec<String>) {
use std::env;
if let Ok(v) = env::var("ALL_SMI_RECORD_OUTPUT_DIR")
&& !v.trim().is_empty()
{
settings.record.output_dir = Some(v);
}
if let Ok(v) = env::var("ALL_SMI_RECORD_COMPRESS") {
match v.as_str() {
"zstd" | "gzip" | "none" => settings.record.compress = v,
other => warnings.push(format!(
"env ALL_SMI_RECORD_COMPRESS: ignored invalid value `{other}`"
)),
}
}
}
fn apply_env_snapshot(settings: &mut Settings, warnings: &mut Vec<String>) {
use std::env;
if let Ok(v) = env::var("ALL_SMI_SNAPSHOT_DEFAULT_FORMAT") {
match v.as_str() {
"json" | "csv" | "prometheus" => settings.snapshot.default_format = v,
other => warnings.push(format!(
"env ALL_SMI_SNAPSHOT_DEFAULT_FORMAT: ignored invalid value `{other}`"
)),
}
}
if let Ok(v) = env::var("ALL_SMI_SNAPSHOT_DEFAULT_PRETTY") {
settings.snapshot.default_pretty = matches!(v.as_str(), "1" | "true" | "TRUE" | "True");
}
}