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

Documentation on hierarchical env is ambiguous and could better illustrate conventions/edge cases #596

Open
j-n-f opened this issue Oct 30, 2024 · 3 comments

Comments

@j-n-f
Copy link

j-n-f commented Oct 30, 2024

Hi, just wanted to offer some feedback on the documentation as a first-time user.

I'm looking at this here: https://github.com/rust-cli/config-rs/blob/main/examples/hierarchical-env/settings.rs

And I think the example could be improved to make it more obvious how it works.

This is probably the best documentation on the feature (as docs.rs didn't really clarify anything for me).

It seems like there's some ambiguity when parsing an env name.

Let's say you have a prefix of MY_APP and a separator of _. If you have some nested config value like security.app_key, then you'd expect an env var like MY_APP_SECURITY_APP_KEY.

The documentation/example doesn't really illustrate how this parsing is happening. That env name could be parsed as:

  • security.app.key
  • security_app.key
  • security_app_key
  • security.app_key

and it's not clear what rules are used to disambiguate. I'm guessing without a struct to deserialize to that all of those keys will match the env.

If I were to parse as a hashmap then I'm guessing it will just take every single underscore that isn't in the prefix as a path separator (security.app.key).

If it were deserialized to a structure with a known format then it will probably look at the fields in every layer of the hierarchy and only select matches that fit that schema.

I could imagine an extreme case like:

struct SecurityApp {
    key: String,
}
struct Security {
    app_key: String,
}
struct AppConfig {
    security: Security,
    security_app: SecurityApp,
}

Where it would either return an error (because it can't decide between security.app_key and security_app.key), or maybe it would store that value in both fields, or maybe it would store it in the first one that matches.

Other systems I've seen in the past disambiguate by defaulting to a path separator of __ (two underscores).

What I'll end up doing is experimenting through trial and error to figure out what the expectations/edge cases are, but I think it would be valuable if the documentation/examples could just make this clearer from the start. If the difference between a carefully designed schema and an ambiguous one have performance/functional implications it would be good to have clarity around that so that appropriate caution can be taken.

@j-n-f
Copy link
Author

j-n-f commented Oct 30, 2024

It looks like it's necessary to use something like __ as a separator if any of your env values have a _ in the name.

@epage
Copy link
Contributor

epage commented Nov 21, 2024

As a heads up, I'm acting as more of a steward than an active contributing maintainer. If you have ideas for how to improve the docs, we'd welcome PRs for it. I do find docs updates are difficult contributions because there is a balance of correctness and understanability as well as making changes "fit in".

@j-n-f
Copy link
Author

j-n-f commented Nov 21, 2024

Sounds good.

I'll see what I can come up with.

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

No branches or pull requests

2 participants