目的
プログラム全体で使いたい設定情報を1つのstructに定義して持ち歩きたいです。actix-webあたりだとWebDataとして各ハンドラーから参照できるようになります。
デフォルト値をもちつつ、値の変更は環境変数で行うものとします。
DBの接続先はテストかどうかで向き先を変えてみます。
プログラム
config.rs
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Config {
pub pg_url: String,
pub redis_url: String,
pub db_retry_count: u64,
pub db_retry_delay: u64,
}
impl Config {
pub fn new() -> Self {
let db_host = get_env_str("DB_HOST", "localhost");
let pgport = get_env_str("PGPORT", "5432");
let postgres_user = get_env_str("POSTGRES_USER", "user");
let postgres_password = get_env_str("POSTGRES_PASSWORD", "password");
// まず本番環境の値を探して、なければテストかどうかで開発かテストを判定
let postgres_db = get_env_str(
"POSTGRES_DB",
&if cfg!(test) {
get_env_str("POSTGRES_DB_TEST", "test")
} else {
get_env_str("POSTGRES_DB_DEV", "development")
},
);
Self {
pg_url: format!(
"postgres://{}:{}@{}:{}/{}",
postgres_user, postgres_password, db_host, pgport, postgres_db
),
redis_url: get_env_str("REDIS_URL", "redis://localhost:6379"),
db_retry_count: get_env_value("DB_RETRY_COUNT", 3),
db_retry_delay: get_env_value("DB_RETRY_DELAY", 2),
}
}
}
// 文字列の値を取得
fn get_env_str(key: &str, default_value: &str) -> String {
match ::std::env::var(key) {
Ok(val) => val,
Err(_) => default_value.to_string(),
}
}
// 文字列以外の値を取得
fn get_env_value<T>(key: &str, default_value: T) -> T
where
T: std::str::FromStr + Copy,
{
match ::std::env::var(key) {
Ok(val) => val.parse().unwrap_or(default_value),
Err(_) => default_value,
}
}