config-rs icon indicating copy to clipboard operation
config-rs copied to clipboard

New Environment method to retrieve variables without removing the prefix

Open jaudiger opened this issue 3 years ago • 4 comments

First of all, I really like the new version 0.12 of config-rs. Thanks for the great work, and continue like that!

I have few cases were I would like to use the following code:

    let settings = Config::builder()
        // Add in settings from the environment (with a prefix of APP)
        // Eg.. `APP_DEBUG=1 ./target/app` would set the `app.debug` key
        .add_source(config::Environment::with("APP"))
        .build()
        .unwrap();

For now, as I can see in the documentation and the examples, there is just an API to retrieve environment variables and this same API removes the current prefix. What I would like is to keep the prefix here.

jaudiger avatar Feb 23 '22 17:02 jaudiger

Have a look at the hierarchical-env example! Running it with ./target/debug/examples/hierarchical-env prints the configuration. If you pass APP_DEBUG=false ./target/debug/examples/hierarchical-env, it sets debugging to false (default true).

I am not sure what you mean by

there is just an API to retrieve environment variables and this same API removes the current prefix.

matthiasbeyer avatar Feb 24 '22 05:02 matthiasbeyer

You are right, let me expand the example I provided in my initial post. I would like to to the following thing:

#[derive(Debug, Deserialize)]
#[allow(unused)]
struct Debug {
    level: String,
    name: String,
}

#[derive(Debug, Deserialize)]
#[allow(unused)]
pub struct Settings {
    debug: Debug,
}

let settings = Config::builder()
    // Add in settings from the environment (with a prefix of DEBUG)
    // Eg.. `DEBUG_LEVEL=1 ./target/app` would set the `debug.level` key
    // Eg.. `DEBUG_NAME=1 ./target/app` would set the `debug.name` key
    .add_source(config::Environment::with("DEBUG"))
    .build()
    .unwrap();

Currently, the example (https://github.com/mehcode/config-rs/blob/master/examples/hierarchical-env/settings.rs) does only allow the following deserialization (if I'm right):

#[derive(Debug, Deserialize)]
#[allow(unused)]
pub struct Settings {
    level: String,
    name: String,
}

let settings = Config::builder()
    // Add in settings from the environment (with a prefix of DEBUG)
    // Eg.. `DEBUG_LEVEL=1 ./target/app` would set the `level` key
    // Eg.. `DEBUG_NAME=1 ./target/app` would set the `name` key
    .add_source(config::Environment::with_prefix("DEBUG"))
    .build()
    .unwrap();

jaudiger avatar Feb 24 '22 06:02 jaudiger

Ah, now I get it. So for the first example, I guess, you would need to DEBUG_DEBUG_LEVEL because you specified DEBUG as a prefix and debug is the key of the setting in struct Settings.

Also, there is no Environment::with, only Environment::with_prefix!

I guess you should be good without a prefix, though!

matthiasbeyer avatar Feb 24 '22 08:02 matthiasbeyer

Yes, I know there is no Environment::with method. But it could be nice to have such method that do not remove the prefix.

Here, my example was intended to be simple, but I'm using config-rs in a project with more than 20-30 configurations parameters that all begin with the same root configuration. And I don't want to add a prefix that is not be part of the configuration file. Even if it could make sense in other cases. I agree with the initial approach of Environment::with_prefix.

I want to reproduce the behavior of what are doing Spring Cloud services with their environment variables:

spring:
    application:
        name: my-app

This variable can be overridden with SPRING_APPLICATION_NAME. What do you think?

jaudiger avatar Feb 24 '22 08:02 jaudiger