envy
envy copied to clipboard
Add "separator" to parse nested structs
💡 Feature description
In config-rs, there's an option to define a separator
which allow users to structure their env vars. I think an example will illustrate better:
#[derive(Deserialize)]
struct Config {
database: Database
}
#[derive(Deserialize)]
struct Database {
name: String,
}
If we define a separator, let's say "__", we could create this Config
by setting DATABASE__NAME=foo
.
Would it be possible and desirable for envy
to include it?
Alternatives
It is possible to get the same behavior using the flatten
attribute from serde (as noticed in #15). The drawback is that it demands a good amount of boilerplate because we would have to serde's rename
every field in the nested struct if we wanted to use this separator idea.
I want to mention one alternative using serde_with::with_prefix
. It's a bit less boilerplate than applying rename
on every field.
It is not a replacement for having it integrated directly into envy
though.
serde_with::with_prefix
solution
serde_with::with_prefix!(pdatabase "database__");
#[derive(Debug, serde::Deserialize)]
struct Config {
#[serde(flatten, with = "pdatabase")]
database: Database,
}
#[derive(Debug, serde::Deserialize)]
struct Database {
name: String,
}
fn main() {
std::env::set_var("DATABASE__NAME", "foobar");
let config: Config = envy::from_env().unwrap();
dbg!(config);
}
Worth noting that flatten
doesnt work with non-String datatypes. c.f. https://github.com/softprops/envy/issues/26