serde-rs / json

Strongly typed JSON library for Rust
Apache License 2.0
4.85k stars 553 forks source link

RawValues inside internally tagged enum #545

Open hweom opened 5 years ago

hweom commented 5 years ago

This code

use serde::Deserialize;
use serde_json; // 1.0.39
use serde_json::value::RawValue;

#[derive(Deserialize, Debug)]
struct Struct<'a> {
    #[serde(borrow)]
    value: &'a RawValue,
}

#[derive(Deserialize, Debug)]
#[serde(tag = "a")]
enum Wrapper<'a> {
    #[serde(rename = "s")]
    S {
        #[serde(borrow)]
        data: Struct<'a>,
    },
}

fn main() {
    let message = r#"{
        "a": "s",
        "data": {
            "value": 123 
        }
    }"#;

    let s: Wrapper = serde_json::from_str(message).unwrap();
    println!("{:?}", s);
}

compiles and runs, but serde_json returns an error: invalid type: newtype struct, expected any valid JSON value

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=84bc58188c5625ce5bbabd6a44da205a

Thomasdezeeuw commented 9 months ago

I've hit this issue as well. @hweom did you find a work around?

Reading https://github.com/serde-rs/json/issues/1051 I understand why flatten won't work with RawValue, but I can't find a reason why enum tagging would interfere. Given the example in the original post, I would expect Struct::value to contain 123, which is directly located in the input JSON.

hweom commented 9 months ago

It's been a while... I think I ended up not using this particular structuring.

wanderinglethe commented 1 month ago

I ran into the same issue (version 1.0.125)

So what would be the solution for this kind of problem? First deserialise just the tag and based on the tag deserialise again?