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

Can't handle #[serde(tag = "someKey")] for structure while Deserialization #318

Open
harshkumar314e opened this issue Oct 18, 2022 · 5 comments

Comments

@harshkumar314e
Copy link

use rmp_serde::Serializer;
use serde::Serialize;

extern crate rmp_serde;
extern crate serde;
#[macro_use]
extern crate serde_derive;

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
struct  A {
    b: B,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "kind", content = "data")]
#[serde(rename_all = "snake_case")]
pub enum B {
    First(i32),
    Second(Messagedata)
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "someKey")]
pub struct Messagedata {
    status: String,
    message: String,
}

fn main() {
    let a = A {
        b: B::Second (Messagedata { status: "Failure".to_string(), message: "You are not getting the things".to_string() }),
    };
    //SERDE
    let string_data = serde_json::to_string(&a).unwrap();
    println!("data: {:?}", string_data);
    let data = serde_json::from_str::<A>(&string_data).unwrap();
    println!("A: {:?}", data);
    println!("-------------------------------------------------------------------------------");

    //MESSAGEPACK
    let mut buf = Vec::new();
    a.serialize(&mut Serializer::new(&mut buf)).unwrap();
    // println!("a: {:?}", buf);
    let a = rmp_serde::from_slice::<A>(&buf).unwrap();
    println!("a: {:?}", a);
}

Here is error I am getting:

data: "{\"b\":{\"kind\":\"second\",\"data\":{\"someKey\":\"Messagedata\",\"status\":\"Failure\",\"message\":\"You are not getting the things\"}}}"
A: A { b: Second(Messagedata { status: "Failure", message: "You are not getting the things" }) }
-------------------------------------------------------------------------------
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: LengthMismatch(2)', src/main.rs:45:46
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

There is no problem with serializing and deserializing with serde. With rmp_serde there is no problem in serializing a struct with a given tag but while deserializing it is not able to take tag provided as key and giving length error.

@kornelski
Copy link
Collaborator

Default encoding doesn't keep field names, so it's unable to know which field was the tag field. If you use .with_struct_map() option it works.

@e-ivkov
Copy link

e-ivkov commented Jun 9, 2023

Here is a more minimalist reproduction of this issue - https://github.com/e-ivkov/rmp-bug-repro

I understand that this is not directly a bug, but I would call it an interface inconsistency. It is natural to expect, that if something serialized successfully, it will also de-serialize back. All other serde libraries behave like that.

I would suggest to always use named serialization in rmp_serde, otherwise it simply does not map to serde interface.

@kornelski
Copy link
Collaborator

It looks like there are hard trade offs here, as some people want the efficient representation.

#319

@shimaowo
Copy link

shimaowo commented Jul 5, 2023

Just seconding the view that the interface inconsistency is actually broken. Anything that can be serialized should successfully deserialize, and vice-versa. I'm all for stripping names unless opted-in, but that doesn't justify self-inconsistent code.

Does this need a from_slice_named() so that it has to be explicit on both sides? The current behavior is just straight broken.

@kornelski
Copy link
Collaborator

Serde doesn't tell the serialiser about existence of any extra options, so at serialisation time there's no way to know if the name is going to be necessary to deserialise or not.

So unfortunately it's up to the user to choose named serialisation if they rely on it.

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

4 participants