config-rs
config-rs copied to clipboard
Enum variant aliases don't work
Here is a failing example demonstrating that enum variant aliases are not taken into account. It also shows a divergence in behavior compared to using serde_json
directly.
#[derive(Debug, serde::Deserialize)]
enum TestEnum {
#[serde(alias = "f")]
Foo,
#[serde(alias = "b")]
Bar,
}
#[derive(Debug, serde::Deserialize)]
struct Wrapper {
test: TestEnum,
}
let json = r#"{"test": "f"}"#;
let w: Wrapper = serde_json::from_str(json).unwrap();
println!("{:?}", w);
let w: Wrapper = config::Config::builder()
.add_source(config::File::from_str(json, config::FileFormat::Json))
.build()
.unwrap()
.try_deserialize()
.unwrap();
println!("{:?}", w);
Output:
Wrapper { t: Foo }
called `Result::unwrap()` on an `Err` value: enum TestEnum does not have variant constructor f
In config-rs
, the variant_seed
cannot create a deserializer on enums with unrecognized values.
https://github.com/mehcode/config-rs/blob/57fb2610ad274dff1d2f2e4d43dfce05ca9c4835/src/de.rs#L279-L293
variant_deserializer
only allows name with given str.
https://github.com/mehcode/config-rs/blob/57fb2610ad274dff1d2f2e4d43dfce05ca9c4835/src/de.rs#L244-L250
I got a straightforward fix to demostrate this, it is not the best.
diff --git a/src/de.rs b/src/de.rs
index 0e2b8de..4d014e9 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -313,8 +313,13 @@ impl<'de> de::EnumAccess<'de> for EnumAccess {
ValueKind::String(ref s) => self.variant_deserializer(s),
ValueKind::Table(ref t) => self.table_deserializer(t),
_ => Err(self.structural_error()),
- }?;
- seed.deserialize(deserializer)?
+ };
+ if let Ok(deserializer) = deserializer {
+ seed.deserialize(deserializer)?
+ } else {
+ let deserializer = self.value.clone();
+ seed.deserialize(deserializer)?
+ }
};
Ok((value, self))