dtolnay / serde-yaml

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

Can't map `!!int` tagged type to Rust type with serde_yaml 0.9 #327

Closed silverjam closed 2 years ago

silverjam commented 2 years ago

In serde_yaml 0.8 the following code is able to map from a !!int tagged type to a Rust u32:

use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct Frob {
    foo: u32,
}

fn main() {
    let value: serde_yaml::Value = serde_yaml::from_str(
        r#"
---
"foo": !!int |-
  7200
"#
    ).unwrap();

    println!("{:?}", value);

    let frob: Frob = serde_yaml::from_str(
        r#"
---
"foo": !!int |-
  7200
"#
    ).unwrap();

    println!("{:?}", frob);
    println!("frob.foo = {}", frob.foo);
}

In serde_yaml 0.9 the following error occurs:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("foo: invalid type: integer `7200`, expected u32", line: 3, column: 8)', main.rs:25:7
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

See gist here https://gist.github.com/silverjam/254c5b6ecd526726e17f89135710034e -- I've also tried other Rust datatypes like i64 but to no avail.

silverjam commented 2 years ago

FWIW this appears to be the output from yaml.safe_dump when using the default_style parameter in the PyYAML library in Python.

>>> import yaml
>>> d = {"foo": 7200}
>>> print(yaml.safe_dump(d, default_style="|"))
"foo": !!int |-
  7200
dtolnay commented 2 years ago

I've published a fix in 0.9.12. Please file other issues if you notice anything else going wrong with this safe_dump/default_style format. This corner of YAML is tricky to get right.

silverjam commented 2 years ago

I've published a fix in 0.9.12. Please file other issues if you notice anything else going wrong with this safe_dump/default_style format. This corner of YAML is tricky to get right.

Wonderful, thank you!