use std::env; use anyhow::{Result, Context, anyhow}; use std::time::Duration; use log::*; const epi: &'static str = "DIPLONAT_PRIVATE_IP"; const ert: &'static str = "DIPLONAT_REFRESH_TIME"; const eet: &'static str = "DIPLONAT_EXPIRATION_TIME"; const ecnd: &'static str = "DIPLONAT_CONSUL_NODE_NAME"; const ecu: &'static str = "DIPLONAT_CONSUL_URL"; pub struct Environment { pub consul_node_name: String, pub consul_url: String, pub refresh_time: Duration, pub expiration_time: Duration, pub private_ip: String, } /* @FIXME: Rewrite with Serde Envi */ impl Environment { pub fn new() -> Result { let ctx = Self { consul_url: match env::var(ecu) { Ok(e) => e, Err(_) => "http://127.0.0.1:8500".to_string() }, consul_node_name: env::var(ecnd).with_context(|| format!("{} env var must be defined", ecnd))?, private_ip: env::var(epi).with_context(|| format!("{} env var must be defined, eg: 192.168.0.18", epi))?, refresh_time: Duration::from_secs(env::var(ert) .with_context(|| format!("{} env var must be defined, eg: 60", ert))? .parse() .with_context(|| format!("{} env var must be an integer, eg: 60", ert))?), expiration_time: Duration::from_secs(env::var(eet) .with_context(|| format!("{} env var must be defined, eg: 300", eet))? .parse() .with_context(|| format!("{} env var must be an integer, eg: 300", eet))?), }; if ctx.refresh_time.as_secs() * 2 > ctx.expiration_time.as_secs() { return Err(anyhow!( "Expiration time (currently: {}s) must be twice bigger than refresh time (currently: {}s)", ctx.refresh_time.as_secs(), ctx.expiration_time.as_secs())); } info!("Consul URL: {:#?}", ctx.consul_url); info!("Consul node name: {:#?}", ctx.consul_node_name); info!("Private IP address: {:#?}", ctx.private_ip); info!("Refresh time: {:#?} seconds", ctx.refresh_time.as_secs()); info!("Expiration time: {:#?} seconds", ctx.expiration_time.as_secs()); return Ok(ctx); } }