dtolnay / serde-yaml

Strongly typed YAML library for Rust
Apache License 2.0
965 stars 164 forks source link

"did not find expected node content" parse regression since 0.8 #387

Open jrray opened 1 year ago

jrray commented 1 year ago

The following test fails on the first case and succeeds on the rest in 0.9. They all succeeded in 0.8.

#[test]
fn test_list_with_colon() {
    let cases = vec![
        indoc! {"
      filter: [:- .gitignore]
    "},
        indoc! {"
      filter:
          - :- .gitignore
    "},
        indoc! {"
      filter: [\":- .gitignore\"]
    "},
        indoc! {"
      filter:
          - \":- .gitignore\"
    "},
    ];
    let mut expected = BTreeMap::new();
    expected.insert("filter", vec![":- .gitignore"]);
    for case in cases {
        test_de_no_value(case, &expected);
    }
}

thread 'test_list_with_colon' panicked at 'called Result::unwrap() on an Err value: Error { kind: PARSER, problem: "did not find expected node content", problem_mark: Mark { line: 1, column: 10 }, context: "while parsing a flow node", context_mark: Mark { line: 1, column: 10 } }', tests/test_de.rs:42:54

I'm having a difficult time interpreting the yaml spec to say whether this is actually legal yaml.

We are in a predicament upgrading to serde_yaml 0.9 because we have a large number of documents with this content in it. It happens that ruamel.yaml (python) serializes a value like this with no quotes, which is how we ended up with these documents:

>>> from ruamel import yaml
>>> yaml.dump({"filter": [":- .gitignore"]})
'filter: [:- .gitignore]\n'

ruamel will parse this back in, but pyyaml will not:

yaml.parser.ParserError: while parsing a flow node
expected the node content, but found ':'
  in "<unicode string>", line 1, column 10:
    filter: [:- .gitignore]
             ^

I realize this probably should be directed at the libyaml project and it isn't directly serde_yaml's fault, but I thought it might be worth logging this 0.8/0.9 incompatibility here.