Skip to content

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

@cafce25

Description

@cafce25

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.

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<String, Box<dyn std::error::Error>> {
    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<dyn std::error::Error>> {
    let mut rdr = csv::Reader::from_reader(data.as_bytes());
    for record in rdr.deserialize::<MaybeRecord>() {
        dbg!(record)?;
    }
    Ok(())
}
fn main() {
    let serialized = serialize().unwrap();
    println!("----\n{serialized}\n----");
    deserialize(&serialized).unwrap();

}

Playground

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions