Skip to content
This repository was archived by the owner on Mar 25, 2024. It is now read-only.

Support tags on sequences and mappings #147

Closed
ExpHP opened this issue Jan 17, 2020 · 4 comments
Closed

Support tags on sequences and mappings #147

ExpHP opened this issue Jan 17, 2020 · 4 comments

Comments

@ExpHP
Copy link

ExpHP commented Jan 17, 2020

See https://users.rust-lang.org/t/help-using-serde-yaml-to-deserialize-value-with-very-many-possible-types/37058

#[derive(Debug, Deserialize)]
enum Parameter {
    vec2(ArrayVec<[f32; 2]>),
    vec3(ArrayVec<[f32; 3]>),
    vec4(ArrayVec<[f32; 4]>),
    curve(Vec<CurveVal>),
    str32(String),
    str64(String),
    str256(String),
    string(String),
}

Currently, this enum type is capable of using tags in place of singleton mappings to disambiguate between its String variants:

- !str32 "hello"
- !string "world"

But it cannot use tags for the sequence-type variants: (it can only use singleton mappings)

# These don't work
- !vec3 [1.0, 0.5, 0.3]
- !curve [1.0, 0.5, 0.3]

# Required workaround
- vec3: [1.0, 0.5, 0.3]
- curve: [1.0, 0.5, 0.3]

A solution to this would appear to be blocked on chyh1990/yaml-rust#147, as the upstream parsing library currently does not emit tags in its SequenceStart or MappingStart events.


Aside: I find it rather amusing how both of these issues ended up being number 147. 😄

@aloucks
Copy link

aloucks commented Jan 18, 2020

It seems that tags don't work on numbers either.

Modified from test_de.rs:

#[test]
fn test_enum_tag() {
    #[derive(Deserialize, PartialEq, Debug)]
    enum E {
        A(String),
        B(String),
        C(f32), // <-- this is new
    }
    #[derive(Deserialize, PartialEq, Debug)]
    struct Data {
        a: E,
        b: E,
        c: E
    }
    let yaml = unindent(
        "
        ---
        a: !A foo
        b: !B bar
        c: !C 1.0",
    );
    let expected = Data {
        a: E::A("foo".into()),
        b: E::B("bar".into()),
        c: E::C(1.0),
    };
    test_de(&yaml, &expected);
}
thread 'test_enum_tag' panicked at 'called `Result::unwrap()` on an `Err` value: Message("invalid type: string \"1.0\", expected f32", Some(Pos { marker: Marker { index: 30, line: 4, col: 6 }, path: "c.C" }))', src\libcore\result.rs:1165:5

@dtolnay
Copy link
Owner

dtolnay commented Jul 28, 2022

Fixed in 0.9.

@dtolnay dtolnay closed this as completed Jul 28, 2022
@pcrumley
Copy link

pcrumley commented Aug 3, 2022

Is there a supported way such that the former workaround of using e.g. vec3: ... instead of !vec3 continues to work, or are users blocked on upgrading to 0.9 until they update the raw yaml files.

Thanks for all your hard work!

@pcrumley
Copy link

pcrumley commented Aug 3, 2022

Just in case someone finds their way here from googling errors like I did, I wanted to update that i answered my own question by looking at another issue and you can uses singleton maps https://docs.rs/serde_yaml/0.9.4/serde_yaml/with/singleton_map/index.html

Thanks again for all the hard work!

Repository owner locked and limited conversation to collaborators Aug 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants