use anyhow::Result; use serde::Deserialize; use crate::config::RuntimeConfig; // This code is inspired by the Trunk crate (https://github.com/thedodd/trunk) // This file parses the options that can be declared in the environment. // runtime.rs applies business logic and builds RuntimeConfig structs. /// Base configuration options #[derive(Clone, Default, Deserialize)] pub struct ConfigOptsBase { /// This node's private IP address [default: None] pub private_ip: Option, /// Expiration time for IGD rules [default: 60] pub expiration_time: Option, /// Refresh time for IGD and Firewall rules [default: 300] pub refresh_time: Option, } /// ACME configuration options #[derive(Clone, Default, Deserialize)] pub struct ConfigOptsAcme { /// Whether ACME is enabled [default: false] #[serde(default)] pub enable: bool, /// The default domain holder's e-mail [default: None] pub email: Option, } /// Consul configuration options #[derive(Clone, Default, Deserialize)] pub struct ConfigOptsConsul { /// Consul's node name [default: None] pub node_name: Option, /// Consul's REST URL [default: "http://127.0.0.1:8500"] pub url: Option, } /// Model of all potential configuration options pub struct ConfigOpts { pub base: ConfigOptsBase, pub acme: ConfigOptsAcme, pub consul: ConfigOptsConsul, } impl ConfigOpts { pub fn from_env() -> Result { let base: ConfigOptsBase = envy::prefixed("DIPLONAT_").from_env()?; let consul: ConfigOptsConsul = envy::prefixed("DIPLONAT_CONSUL_").from_env()?; let acme: ConfigOptsAcme = envy::prefixed("DIPLONAT_ACME_").from_env()?; RuntimeConfig::new(Self { base: base, consul: consul, acme: acme, }) } pub fn from_iter(iter: Iter) -> Result where Iter: IntoIterator { let base: ConfigOptsBase = envy::prefixed("DIPLONAT_").from_iter(iter.clone())?; let consul: ConfigOptsConsul = envy::prefixed("DIPLONAT_CONSUL_").from_iter(iter.clone())?; let acme: ConfigOptsAcme = envy::prefixed("DIPLONAT_ACME_").from_iter(iter.clone())?; RuntimeConfig::new(Self { base: base, consul: consul, acme: acme, }) } }