3Hren / 3Hren/msgpack-rust

Fails to deserialize adjacent enum unit and struct variants

Open
#250 7 comments 5 reactions 0 assignees View on GitHub
M: help wanted T: bug
Dominant language
Rust
Stars
1.4k
Forks
162
PR merge metrics
No merged PRs in 30d

Description

## Description

I believe that I have encountered some bugs when attempting to convert from msgpack back into a Rust enumeration when using adjacent tagging. This is not a problem for msgpack if I only do inner tagging.

I've attached a fully working, minimal example where the tests can highlight working and failing scenarios: [msgpack-rust-bug.zip](https://github.com/3Hren/msgpack-rust/files/4741027/msgpack-rust-bug.zip)

I've also highlighted most relevant parts below including the version of serde and rmp-serde used as well as highlighting working adjacent serialization and deserialization with JSON.

## Cargo.toml:

```toml
[dependencies]
serde = { version = "1.0.111", features = ["derive"] }
serde_json = { version = "1.0.48" }
rmp-serde = "0.14.3"
```

## Example Setup

For code like this:
```rust
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(tag = "type", content = "payload")]
pub enum Example {
Unit1,
Unit2,
HasValue { x: u32 },
TupleWithValue(u32, u32),
InnerValue(SomeInnerValue),
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct SomeInnerValue {
pub a: u32,
pub b: String,
}
```

## Struct Variant Failure

```rust
let v = rmp_serde::to_vec(&Example::HasValue { x: 3 }).unwrap();

// Fails unwrap with Syntax("invalid type: sequence,
// expected struct variant Example::HasValue")
let ex: Example = rmp_serde::from_slice(&v).unwrap();
assert_eq!(Example::HasValue { x: 3 }, ex);
```

## Unit Variant Failure

```rust
let v = rmp_serde::to_vec(&Example::Unit1).unwrap();

// Fails unwrap with Syntax("invalid length 1,
// expected adjacently tagged enum Example")
let ex: Example = rmp_serde::from_slice(&v).unwrap();
assert_eq!(Example::Unit1, ex);
```

## Success with serde json

```rust
let json_text = "{\"type\":\"Unit1\"}";
let ex: Example = serde_json::from_str(json_text).unwrap();
let output = serde_json::to_string(&ex).unwrap();
assert_eq!(json_text, output);

let v = serde_json::to_vec(&Example::HasValue { x: 3 }).unwrap();
let ex: Example = serde_json::from_slice(&v).unwrap();
assert_eq!(Example::HasValue { x: 3 }, ex);

let v = serde_json::to_vec(&Example::TupleWithValue(1, 2)).unwrap();
let ex: Example = serde_json::from_slice(&v).unwrap();
assert_eq!(Example::TupleWithValue(1, 2), ex);
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.