BurntSushi / BurntSushi/rust-csv

Cannot Deserialize Serialize output when outer type is an untagged enum.

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

Description

#### What version of the `csv` crate are you using?

1.3.0

#### Briefly describe the question, bug or feature request.

I want to deserialize different rows of a CSV file differently depending on wether a field can be serialized into an enum or is empty, I tried using a `#[serde(untagged)]` enum for that, but although that produces the expected output when serializing, it does fail to deserialize it (and it's own output).

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

```rust
use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(untagged)]
enum MaybeRecord {
Record(Record),
Partial(Partial),
}
#[derive(Debug, Serialize, Deserialize, Clone)]
struct Partial {
name: String,
ty: (),
}
#[derive(Debug, Serialize, Deserialize, Clone)]
enum Ty {
One,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Record{
name: String,
ty: Ty,
}

fn serialize() -> Result> {
let mut wrtr = csv::Writer::from_writer(Vec::new());
wrtr.serialize(&MaybeRecord::Partial(Partial {
name: String::from("baz"),
ty: (),
}))?;
wrtr.serialize(&MaybeRecord::Record(Record {
name: String::from("foo"),
ty: Ty::One,
}))?;
Ok(String::from_utf8(wrtr.into_inner()?)?)
}
fn deserialize(data: &str) -> Result<(), Box> {
let mut rdr = csv::Reader::from_reader(data.as_bytes());
for record in rdr.deserialize::() {
dbg!(record)?;
}
Ok(())
}
fn main() {
let serialized = serialize().unwrap();
println!("----\n{serialized}\n----");
deserialize(&serialized).unwrap();

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

#### What is the observed behavior of the code above?
Standard Error
```
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 1.01s
Running `target/debug/playground`
[src/main.rs:40:9] record = Err(
Error(
Deserialize {
pos: Some(
Position {
byte: 8,
line: 2,
record: 1,
},
),
err: DeserializeError {
field: None,
kind: Message(
"data did not match any variant of untagged enum MaybeRecord",
),
},
},
),
)
thread 'main' panicked at src/main.rs:47:30:
called `Result::unwrap()` on an `Err` value: Error(Deserialize { pos: Some(Position { byte: 8, line: 2, record: 1 }), err: DeserializeError { field: None, kind: Message("data did not match any variant of untagged enum MaybeRecord") } })
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

Standard Output
```
----
name,ty
baz,
foo,One

----
```

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

While stdout shows that serialization was successfull, deserializing that very output fails.

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.