Hey, first of all, thanks for the library. It's great especially compared to envy
since it supports nested structs.
I am having a weird issue when defaults are involved. I worked around it for now, but I am still confused about why it is happening, and I would love to contribute a fix if you can give me some context in the code and point me to it.
Code
use color_eyre::Result;
use serde::Deserialize;
use serde_default::DefaultFromSerde;
use serde_env::from_env;
fn default_sampler_arg() -> f64 {
1.0
}
#[derive(Debug, Clone, Deserialize, DefaultFromSerde)]
pub struct OTELTracesConfig {
#[serde(default = "default_sampler_arg")]
pub sampler_arg: f64,
}
#[derive(Debug, Clone, Deserialize, DefaultFromSerde)]
pub struct OTELConfig {
pub traces: OTELTracesConfig,
}
#[derive(Debug, Clone, Deserialize, DefaultFromSerde)]
pub struct Config {
pub otel: OTELConfig,
}
fn main() -> Result<()> {
println!("default: {:#?}", Config::default());
println!("from_env: {:#?}", from_env::<Config>()?);
Ok(())
}
Expected
with no env vars
default: Config {
otel: OTELConfig {
traces: OTELTracesConfig {
sampler_arg: 1.0,
},
},
}
from_env: Config {
otel: OTELConfig {
traces: OTELTracesConfig {
sampler_arg: 1.0,
},
},
}
with env var OTEL_TRACES_SAMPLER_ARG=0.5
default: Config {
otel: OTELConfig {
traces: OTELTracesConfig {
sampler_arg: 1.0,
},
},
}
from_env: Config {
otel: OTELConfig {
traces: OTELTracesConfig {
sampler_arg: 0.5,
},
},
}
Actual
with no env vars
default: Config {
otel: OTELConfig {
traces: OTELTracesConfig {
sampler_arg: 1.0,
},
},
}
Error: missing field `otel`
Location:
src/main.rs:28:33
with env var OTEL_TRACES_SAMPLER_ARG=0.5
working correctly
Workaround
It works if I add #[serde(default)]
to otel
in Config
.
#[derive(Debug, Clone, Deserialize, DefaultFromSerde)]
pub struct Config {
#[serde(default)]
pub otel: OTELConfig,
}
There are 2 issues regarding this though:
- Why do I need to add
#[serde(default)]
? Default
is implemented for OTELConfig
and implementing Default
for Config
should automatically pick it up.
- If I need to add the above, why do I not need to add it for
traces
in OTELConfig
? Why is it only required to do so for Config
struct?
Because of the 2 issues I mentioned above, my instinct says that this is an issue with the deserialization in this library. Please let me know how I can help to fix this.
Thanks again.