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

[lowpri] serialization of containers-in-structs errors differently depending on the circumstances #218

Open
guswynn opened this issue Jan 7, 2021 · 1 comment

Comments

@guswynn
Copy link

guswynn commented Jan 7, 2021

Thank you for taking the time to file a bug report. The following describes
some guidelines to creating a minimally useful ticket.

Above all else: do not describe your problem, SHOW your problem.

What version of the csv crate are you using?

1.1.5

Briefly describe the question, bug or feature request.

I was looking into how the csv crate implemented serde serialization/deserialization, and noticed a discrepancy.

In this case: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0093262a4a6e3a775a70df76c8e9a91f

use std::error::Error;
use std::io;
use std::process;
use csv; // 1.1.5
use serde;

use serde::Serialize;

#[derive(Debug, Serialize)]
struct Record {
    city: String,
    region: String,
    country: String,
    population: Option<u64>,
    v: Vec<i64>,
}

fn example() -> Result<(), Box<dyn Error>> {
    let mut wtr = csv::Writer::from_writer(io::stdout());

    // When writing records with Serde using structs, the header row is written
    // automatically.
    wtr.serialize(Record {
        city: "Southborough".to_string(),
        region: "MA".to_string(),
        country: "United States".to_string(),
        population: Some(9686),
        v: vec![1, 2, 3, 4],
    })?;
    wtr.serialize(Record {
        city: "Northbridge".to_string(),
        region: "MA".to_string(),
        country: "United States".to_string(),
        population: Some(14061),
        v: vec![1, 2, 3, 4],
    })?;
    wtr.flush()?;
    Ok(())
}

fn main() {
    if let Err(err) = example() {
        println!("error running example: {}", err);
        process::exit(1);
    }
}

outputs

city,region,country,population,verror running example: CSV write error: cannot serialize sequence container inside struct when writing headers from structs

It very clearly states that the problem is, serializing containers in a struct is impossible.

However
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d9fe9283bd43cfce5fc9bebbde843ef3

    wtr.serialize(Record {
        city: "Southborough".to_string(),
        region: "MA".to_string(),
        country: "United States".to_string(),
        population: Some(9686),
        v: Some(vec![1, 2, 3, 4]),
    })?;
    wtr.serialize(Record {
        city: "Northbridge".to_string(),
        region: "MA".to_string(),
        country: "United States".to_string(),
        population: Some(14061),
        v: Some(vec![1, 2, 3, 4]),
    })?;

outputs

city,region,country,population,v
Southborough,MA,United States,9686,1,2,3,4error running example: CSV error: found record with 8 fields, but the previous record has 5 fields

showing that only the Writer notices the problem of "containers-in-structs" when it notices there are too many fields.

Similarly https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=275fdb4cf35a29bb47786590c699bcfc
shows that things like tuple structs fail late as well, and https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=275fdb4cf35a29bb47786590c699bcfc shows that top-level sequences only work if they are the exact same size.

Looking into the code of the serializer, and thinking about how csv works, it makes sense why this behavior is the way it is, however, I am wondering, do you think it would be worth it to restructure the serializer so it could give better error messages? I would be willing to look into this, unless you think its not possible/very difficult

@guswynn guswynn changed the title [lowpri] serialization of containers-in-structs errors differently if its the first [lowpri] serialization of containers-in-structs errors differently depending on the circumstances Jan 7, 2021
@jayvdb
Copy link

jayvdb commented Aug 19, 2024

Semi-related: #342

In addition to improving the errors, IMO it would be very helpful to detect if serde is being used, and recommend flattening the unsupported struct using https://crates.io/crates/serde_with

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

2 participants