Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I use environment variables in configuration file? #447

Closed
dev-davexoyinbo opened this issue Aug 6, 2023 · 2 comments
Closed

How do I use environment variables in configuration file? #447

dev-davexoyinbo opened this issue Aug 6, 2023 · 2 comments

Comments

@dev-davexoyinbo
Copy link

How do I use environment variables in configuration file?

database_configuration:
  postgres_host: ${postgres_host}
  postgres_port: 5432
  postgres_user: admin
  postgres_password: password123
  postgres_db: rust_jwt_authentication

I keep getting the postgres host as the string "${postgres_host}" instead of the value postgres_host from the .env file

@matthiasbeyer
Copy link
Member

This crate does not support such functionality. You should use a templating library like handlebars for that!

@matthiasbeyer matthiasbeyer closed this as not planned Won't fix, can't repro, duplicate, stale Aug 6, 2023
@dev-davexoyinbo
Copy link
Author

Thanks for the suggestion, I've been able to rewrite it to do that

use std::collections::HashMap;

use config::{Config, ConfigError, File, FileFormat};

#[derive(serde::Deserialize, serde::Serialize, Debug)]
pub struct AppConfiguration {
    database_configuration: DatabaseConfiguration,
}

impl AppConfiguration {
    pub fn get_configuration() -> Result<AppConfiguration, ConfigError> {
        let base_path = std::env::current_dir().expect("Failed to determine the current directory");
        let configuration_path = base_path.join("configurations");

        let env_string = std::fs::read_to_string(".env").unwrap_or("".to_string());
        let environment_data: HashMap<String, String> = Config::builder()
            .add_source(File::from_str(&env_string, FileFormat::Ini))
            .build()?
            .try_deserialize()?;

        let handlebars = handlebars::Handlebars::new();
        let template_string = std::fs::read_to_string(configuration_path.join("base.yaml"))
            .expect("Unable to open configuration file");

        let rendered = handlebars
            .render_template(&template_string, &environment_data)
            .expect("Unable to render template");

        let builder = Config::builder()
            .add_source(File::from_str(rendered.as_str(), FileFormat::Yaml).required(true));

        return builder.build()?.try_deserialize();
    }
}

#[derive(serde::Deserialize, serde::Serialize, Debug)]
pub struct DatabaseConfiguration {
    postgres_host: String,
    postgres_port: u32,
    postgres_user: String,
    postgres_password: String,
    postgres_db: String,
}

configuration/base.yaml

database_configuration:
  postgres_host: {{postgres_host}}
  postgres_port: {{postgres_port}}
  postgres_user:  {{postgres_user}}
  postgres_password:  {{postgres_password}}
  postgres_db:  {{postgres_db}}

.env

postgres_host=127.0.0.1
postgres_port=6500
postgres_user=admin
postgres_password=password123
postgres_db=rust_jwt_authentication

main.rs

let app_configurations = AppConfiguration::get_configuration().expect("Unable to build configuration");
println!("{:?}", app_configurations);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants