BurntSushi / BurntSushi/rust-csv

Error Deserializing Struct With `flatten`-ed Tagged Enum

Open
#278 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2k
Forks
257
PR merge metrics
No merged PRs in 30d

Description

#### Version

Tested on both `v1.1.6` and `master` branch.

#### Briefly describe the bug.

Deserializing a struct with a flattened tagged enum field does not seem to work.

#### Include a complete program demonstrating a problem.

Code:

```rust
#![allow(dead_code)]

use serde::de::DeserializeOwned;
use std::fmt::Debug;

mod tagged_enum {
use serde::Deserialize;

#[derive(Debug, Deserialize)]
pub struct Record {
common: u64,
#[serde(flatten)]
kind: Kind,
}

#[derive(Debug, Deserialize)]
#[serde(tag = "kind", content = "parameter", rename_all = "lowercase")]
enum Kind {
Foo(u64),
Bar(bool),
}
}

mod flattened_struct {
use serde::Deserialize;

#[derive(Debug, Deserialize)]
pub struct Record {
common: u64,
#[serde(flatten)]
inner: Inner,
}

#[derive(Debug, Deserialize)]
struct Inner {
kind: Kind,
parameter: Value,
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
enum Kind {
Foo,
Bar,
}

#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum Value {
Num(u64),
Bool(bool),
}
}

const CSV: &[u8] = b"\
common,kind,parameter
1,foo,42
2,bar,true";

fn dbg_records()
where
T: Debug + DeserializeOwned,
{
let mut reader = csv::Reader::from_reader(CSV);
for record in reader.deserialize::() {
println!("{:#?}", record);
}
}

fn main() {
dbg_records::(); // Error!
dbg_records::(); // OK.
}
```

([Playground link](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a7006934525c7c22b7acf68d9bd058cc)).

#### What is the observed behavior of the code above?

Fails to deserialize with invalid type: byte array, expected "kind", "parameter", or other ignored fields error:

```
Err(
Error(
Deserialize {
pos: Some(
Position {
byte: 22,
line: 2,
record: 1,
},
),
err: DeserializeError {
field: None,
kind: Message(
"invalid type: byte array, expected \"kind\", \"parameter\", or other ignored fields",
),
},
},
),
)
Err(
Error(
Deserialize {
pos: Some(
Position {
byte: 31,
line: 3,
record: 2,
},
),
err: DeserializeError {
field: None,
kind: Message(
"invalid type: byte array, expected \"kind\", \"parameter\", or other ignored fields",
),
},
},
),
)
```

#### What is the expected or desired behavior of the code above?

To correctly deserialize records as they are done in the case of flattened structs (also included in code example).

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.