zero4rs 2.0.0

zero4rs is a powerful, pragmatic, and extremely fast web framework for Rust
Documentation
use lazy_static::lazy_static;

use std::fs;
use std::path::PathBuf;

use crate::commons;
use crate::core::config as Config;

lazy_static! {
    static ref RS_ENV_PREFIX: &'static str = "RS_ENV";
    static ref CONFIG_FILE_NAME: &'static str = "application";
    static ref DOT_ENV_FILE_NAME: &'static str = ".env";
}

fn config_file(file_full_name: Option<&str>, ext: &str, env: &str) -> String {
    let configurati_filename = if env.is_empty() {
        format!("{}.{}", file_full_name.unwrap(), ext)
    } else {
        format!("{}_{}.{}", file_full_name.unwrap(), env, ext)
    };

    if file_exists(&configurati_filename) {
        commons::print_line(format!(
            "Configuration loaded successful: file_path={}",
            // &configurati_filename.replacen(path, ".", 1)
            &configurati_filename
        ));
    }

    configurati_filename
}

pub fn get_configuration(
    env_name: &str,
    config_folder: &str,
) -> Result<Config::Settings, config::ConfigError> {
    let config_folder_path = PathBuf::from(config_folder);
    let config_file_name = config_folder_path.join(*CONFIG_FILE_NAME);

    #[rustfmt::skip]
    let configurati_filename_ini = config_file(config_file_name.to_str(), "ini", "");
    let environment_filename_ini = config_file(config_file_name.to_str(), "ini", env_name);
    let configurati_filename_yml = config_file(config_file_name.to_str(), "yaml", "");
    let environment_filename_yml = config_file(config_file_name.to_str(), "yaml", env_name);

    // 加载环境变量
    loading_env(config_folder, vec![&DOT_ENV_FILE_NAME]);

    #[rustfmt::skip]
    let settings = config::Config::builder()
        .add_source(config::File::new(&configurati_filename_ini, config::FileFormat::Ini).required(false))
        .add_source(config::File::new(&configurati_filename_yml, config::FileFormat::Yaml).required(false))
        .add_source(config::File::new(&environment_filename_ini, config::FileFormat::Ini).required(false))
        .add_source(config::File::new(&environment_filename_yml, config::FileFormat::Yaml).required(false))
        // Add in settings from environment variables (with a prefix of ENV and '__' as separator)
        // E.g. `RS_ENV_APPLICATION_PORT=5001 would set `Settings.application.port`
        // .add_source(config::Environment::with_prefix(*RS_ENV_PREFIX).prefix_separator("_").separator("__"))
        .add_source(config::Environment::with_prefix(*RS_ENV_PREFIX).prefix_separator("_"))
        .build()?;

    settings.try_deserialize::<Config::Settings>()
}

pub fn loading_env(config_path: &str, env_files: Vec<&str>) {
    for file_name in env_files {
        let current_file_name = std::path::Path::new(config_path)
            .join(file_name)
            .display()
            .to_string();

        match dotenv::from_filename(&current_file_name) {
            Ok(_) => commons::print_line(format!(
                "Load environment file success: config_file={}",
                current_file_name
            )),
            Err(e) => commons::print_line(format!(
                "Could not load environment file: config_file={}, error_message='{}'",
                current_file_name, e
            )),
        }
    }
}

pub fn file_exists(file_path: &str) -> bool {
    fs::metadata(file_path).is_ok()
}