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

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

Open
cafce25 opened this issue Apr 18, 2024 · 0 comments
Open

Comments

@cafce25
Copy link

cafce25 commented Apr 18, 2024

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.

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

1 participant