2020-04-22 20:38:22 +02:00
|
|
|
pub use self::deployment_cfg::Deployment;
|
|
|
|
pub use self::postgres_cfg::Postgres;
|
|
|
|
pub use self::redis_cfg::Redis;
|
2020-04-13 22:03:06 +02:00
|
|
|
|
|
|
|
use self::environmental_variables::EnvVar;
|
2020-04-22 20:38:22 +02:00
|
|
|
|
2020-04-13 22:03:06 +02:00
|
|
|
use hashbrown::HashMap;
|
|
|
|
use std::env;
|
2020-04-22 20:38:22 +02:00
|
|
|
use std::fmt;
|
2020-04-13 22:03:06 +02:00
|
|
|
mod deployment_cfg;
|
|
|
|
mod deployment_cfg_types;
|
|
|
|
mod environmental_variables;
|
|
|
|
mod postgres_cfg;
|
|
|
|
mod postgres_cfg_types;
|
|
|
|
mod redis_cfg;
|
|
|
|
mod redis_cfg_types;
|
|
|
|
|
2020-04-22 20:38:22 +02:00
|
|
|
type Result<T> = std::result::Result<T, Error>;
|
2020-04-15 02:37:49 +02:00
|
|
|
|
|
|
|
pub fn merge_dotenv() -> Result<()> {
|
|
|
|
let env_file = match env::var("ENV").ok().as_deref() {
|
2020-04-13 22:03:06 +02:00
|
|
|
Some("production") => ".env.production",
|
|
|
|
Some("development") | None => ".env",
|
2020-04-22 20:38:22 +02:00
|
|
|
Some(v) => Err(Error::config("ENV", v, "`production` or `development`"))?,
|
2020-04-15 02:37:49 +02:00
|
|
|
};
|
|
|
|
let res = dotenv::from_filename(env_file);
|
|
|
|
|
|
|
|
if let Ok(log_level) = env::var("RUST_LOG") {
|
|
|
|
if res.is_err() && ["warn", "info", "trace", "debug"].contains(&log_level.as_str()) {
|
|
|
|
eprintln!(
|
|
|
|
" WARN: could not load environmental variables from {:?}\n\
|
|
|
|
{:8}Are you in the right directory? Proceeding with variables from the environment.",
|
|
|
|
env::current_dir().unwrap_or_else(|_|"./".into()).join(env_file), ""
|
|
|
|
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2020-04-13 22:03:06 +02:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2020-04-15 02:37:49 +02:00
|
|
|
#[allow(clippy::implicit_hasher)]
|
|
|
|
pub fn from_env<'a>(
|
|
|
|
env_vars: HashMap<String, String>,
|
|
|
|
) -> Result<(Postgres, Redis, Deployment<'a>)> {
|
2020-04-13 22:03:06 +02:00
|
|
|
let env_vars = EnvVar::new(env_vars);
|
2020-04-15 02:37:49 +02:00
|
|
|
log::info!(
|
|
|
|
"Flodgatt received the following environmental variables:{}",
|
|
|
|
&env_vars
|
|
|
|
);
|
|
|
|
|
|
|
|
let pg_cfg = Postgres::from_env(env_vars.clone())?;
|
|
|
|
log::info!("Configuration for {:#?}", &pg_cfg);
|
|
|
|
let redis_cfg = Redis::from_env(env_vars.clone())?;
|
|
|
|
log::info!("Configuration for {:#?},", &redis_cfg);
|
|
|
|
let deployment_cfg = Deployment::from_env(&env_vars)?;
|
|
|
|
log::info!("Configuration for {:#?}", &deployment_cfg);
|
|
|
|
|
|
|
|
Ok((pg_cfg, redis_cfg, deployment_cfg))
|
2020-04-13 22:03:06 +02:00
|
|
|
}
|
2020-04-22 20:38:22 +02:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Error {
|
|
|
|
Config(String),
|
|
|
|
UrlEncoding(urlencoding::FromUrlEncodingError),
|
|
|
|
UrlParse(url::ParseError),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::error::Error for Error {}
|
|
|
|
|
|
|
|
impl fmt::Display for Error {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> {
|
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"{}",
|
|
|
|
match self {
|
|
|
|
Self::Config(e) => e.to_string(),
|
|
|
|
Self::UrlEncoding(e) => format!("could not parse POSTGRES_URL.\n{:7}{:?}", "", e),
|
|
|
|
Self::UrlParse(e) => format!("could parse Postgres URL.\n{:7}{}", "", e),
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Error {
|
|
|
|
pub fn config<T: fmt::Display>(var: T, value: T, allowed_vals: T) -> Self {
|
|
|
|
Self::Config(format!(
|
|
|
|
"{0} is set to `{1}`, which is invalid.\n{3:7}{0} must be {2}.",
|
|
|
|
var, value, allowed_vals, ""
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<urlencoding::FromUrlEncodingError> for Error {
|
|
|
|
fn from(e: urlencoding::FromUrlEncodingError) -> Self {
|
|
|
|
Self::UrlEncoding(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<url::ParseError> for Error {
|
|
|
|
fn from(e: url::ParseError) -> Self {
|
|
|
|
Self::UrlParse(e)
|
|
|
|
}
|
|
|
|
}
|