serde-rs / json

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

`Box<RawValue>` and `#[serde(flatten)]` don't work together for deserialization #1099

Closed tbu- closed 9 months ago

tbu- commented 9 months ago

See #883, which was mistakenly closed as being a duplicate of #1051.

dtolnay commented 9 months ago

As far as I can tell, this is a duplicate of #1051. That issue is about Box<RawValue> and #[serde(flatten)] not working together for deserialization when Box<RawValue> appears somewhere inside the flattened data structure. Could you please explain what aspect of it is not duplicated?

tbu- commented 9 months ago

In the example you gave,

#[derive(Deserialize, Debug)]
struct Repro {
    id: String,
    #[serde(flatten)]
    value: Box<RawValue>,
}

I find it clear that the RawValue can't work.

If there's an indirection (another struct) between #[serde(flatten)] and the Box<RawValue> though, it should be possible to make it work, e.g. in the example of #883, we have the following:

#![allow(dead_code)]

use serde::Deserialize;
use std::error::Error;

#[derive(Deserialize)]
struct Abc {
    #[serde(flatten)]
    pub def: Def,
}

#[derive(Deserialize)]
struct Def {
    pub ghi: Box<serde_json::value::RawValue>,
}

fn main() -> Result<(), Box<dyn Error>> {
    let _: Def = serde_json::from_str(r#"{"ghi": {}}"#).unwrap();
    let _: Abc = serde_json::from_str(r#"{"ghi": {}}"#).unwrap();
    Ok(())
}

As we can see, the "raw json string" of the "ghi" key will always be contiguous, so it should™ be possible to create the RawValue.

Upon re-reading #1051, I can now see how the issues are closer than I thought, so I see why it was marked as duplicate. I feel the reasoning given there doesn't apply here though. It makes sense that a raw value doesn't work if directly marked as #[serde(flatten)].

dtolnay commented 9 months ago

I think the indirection is incidental to the reason this isn't working, so they are duplicates. It is possible to do it differently but that is tracked by https://github.com/serde-rs/serde/issues/1183.