Strange error when using a BTreeMap as the key to another map
anthrotype opened this issue · 0 comments
Hello, thanks for this library!
I would like to use serde_yaml to serialize a type that contains BTreeMaps nested inside another BTreeMap, but not as the values but rather as its keys.. I know YAML allows maps to have complex keys whose type is not a mere string or scalar type, using the special ?
prefix in front of the complex key.
This seems to be working most of the time, however I am getting a weird error message when the map that contains such complex keys contains only one item:
Error { kind: EMITTER, problem: "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS" }
Now, the error disappears when the map contains more than one items...
Here's an example below where I hacked serde_yaml's own test_serde.rs from my fork to reproduce this bug.
https://github.com/dtolnay/serde-yaml/compare/master...anthrotype:serde-yaml:map-as-map-key?expand=1
#[test]
fn test_map_as_key_to_another_map() {
// Trying to use a BTreeMap as the key for an other BTreeMap. If the map only
// contains one item, a strange error is returned by the libyaml emitter:
// "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS". If it contains
// more than one item, then serialization completes without errors.
use std::collections::BTreeMap;
use std::path::PathBuf;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
struct Glyph {
name: String,
sources: BTreeMap<BTreeMap<String, i32>, PathBuf>,
}
let yaml = indoc! {"\
name: foo
sources:
? Weight: 400
: Font-Regular.ufo/glyphs/foo.glif
"};
let glyph = Glyph {
name: "foo".to_string(),
sources: vec![
(
BTreeMap::from([("Weight".to_string(), 400)]),
PathBuf::from("Font-Regular.ufo/glyphs/foo.glif"),
),
// // After uncommenting below, it no longer returns an error
// (
// BTreeMap::from([("Weight".to_string(), 700)]),
// PathBuf::from("Font-Bold.ufo/glyphs/foo.glif"),
// ),
]
.into_iter()
.collect(),
};
test_serde(&glyph, yaml);
}
Running cargo test
I get this:
failures:
---- test_map_as_key_to_another_map stdout ----
thread 'test_map_as_key_to_another_map' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: EMITTER, problem: "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS" }', tests/test_serde.rs:20:52
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
test_map_as_key_to_another_map
test result: FAILED. 31 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
error: test failed, to rerun pass `--test test_serde`
Am I doing something wrong? It looks to me it is a bug since it only fails when the map contains one item.