Unable to deserialize number as string for HashMap if flattened or inside untagged enum
Opened this issue · 0 comments
vallentin commented
Given the following YAML:
env:
foo: 123
- It successfully deserializes, when
env: HashMap<String, String>
is inside astruct
- It fails to deserialize if inside an
untagged
enum
- It fails to deserialize if the
struct
isflatten
ed inside anotherstruct
- It successfully deserializes if
struct
is notflatten
ed inside anotherstruct
I understand why. It just feels very inconsistent. It seems that 123
gets deserialized into a number, before the context of interpreting it as a string is known. So that context is lost, and it then fails to deserialize.
Minimal Example
#![allow(dead_code)]
use serde::Deserialize;
use std::collections::HashMap;
#[derive(Deserialize, Debug)]
struct Data1 {
env: HashMap<String, String>,
}
#[derive(Deserialize, Debug)]
#[serde(untagged)]
enum Data2 {
Data { env: HashMap<String, String> },
}
#[derive(Deserialize, Debug)]
#[serde(untagged)]
enum Data3 {
Data(Data1),
}
#[derive(Deserialize, Debug)]
struct Data4 {
#[serde(flatten)]
dat: Data1,
}
fn main() {
let yaml = r#"
env:
foo: bar
"#;
println!();
let dat = serde_yaml::from_str::<Data1>(yaml); // Ok
println!("{:?}", dat);
let dat = serde_yaml::from_str::<Data2>(yaml); // Ok
println!("{:?}", dat);
let dat = serde_yaml::from_str::<Data3>(yaml); // Ok
println!("{:?}", dat);
let dat = serde_yaml::from_str::<Data4>(yaml); // Ok
println!("{:?}", dat);
let yaml = r#"
env:
foo: 123
"#;
println!();
let dat = serde_yaml::from_str::<Data1>(yaml); // Ok
println!("{:?}", dat);
let dat = serde_yaml::from_str::<Data2>(yaml); // Err?
println!("{:?}", dat);
let dat = serde_yaml::from_str::<Data3>(yaml); // Err?
println!("{:?}", dat);
let dat = serde_yaml::from_str::<Data4>(yaml); // Err?
println!("{:?}", dat);
}