Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Struct with flatten field serialized as JSON, but not as struct #548

Open
apatrushev opened this issue Oct 1, 2024 · 4 comments
Open

Struct with flatten field serialized as JSON, but not as struct #548

apatrushev opened this issue Oct 1, 2024 · 4 comments

Comments

@apatrushev
Copy link

apatrushev commented Oct 1, 2024

Struct without flatten field serialized as struct:

use serde::{Deserialize, Serialize};
use serde_json::json;


#[derive(Debug, Deserialize, Serialize)]
struct Event {
    sender: String,
}


fn main() {
    let event = json!({
        "sender": "foobar",
    });
    let event = event.to_string();
    let event = serde_json::from_str::<Event>(&event).unwrap();
    let value = ron::to_string(&event).unwrap();
    println!("{}", value);
}

Result:

(sender:"foobar")

Struct containing flatten field serialized as JSON:

use std::collections::HashMap;

use serde::{Deserialize, Serialize};
use serde_json::json;


#[derive(Debug, Deserialize, Serialize)]
struct Event {
    sender: String,

    #[serde(flatten)]
    extra: HashMap<String, String>,
}


fn main() {
    let event = json!({
        "sender": "foobar",
        "info": "test"
    });
    let event = event.to_string();
    let event = serde_json::from_str::<Event>(&event).unwrap();
    let value = ron::to_string(&event).unwrap();
    println!("{}", value);
}

Result:

{"sender":"foobar","info":"test"}

May be it would be better to see it as (literally ignore the flatten attribute for the fields on serialization may be optionally):

(sender:"foobar", extra: {"info":"test"})
@juntyr
Copy link
Member

juntyr commented Oct 1, 2024

This is unfortunately serde's fault and ron cannot do anything about it.

When a struct contains any flattened fields, serde serializes it as a map (since serializing a struct requires having statically known field names) and not a struct. From ron's point of view, we just get a map from serde and have no idea that it was ever a struct.

@mxgrey
Copy link

mxgrey commented Jan 20, 2025

I just ran into this myself. It's disappointing to not be able to use flatten with RON.

Has there been any consideration for allowing RON's map syntax { } to be automatically coerced into a struct if the strings of the keys match the field names and the values they map to match the respective field types?

I understand this might not fully align with the intention of the syntax having an explicit distinction between structs and maps, but I might think of it as "maps with string keys can be treated as structs of anonymous type".

@juntyr
Copy link
Member

juntyr commented Jan 20, 2025

Do you mean during serialization (unfortunately impossible since serde doesn't give us any information) or during deserialization (should already be working on the 0.9 pre-release version)?

@mxgrey
Copy link

mxgrey commented Jan 20, 2025

Thanks for pointing that out, I didn't think of trying the latest master. That does exactly what I was proposing, so that's great.

I did run into a separate bug while trying that out, so I've opened an issue ticket for that: #555

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants