BurntSushi / BurntSushi/rust-csv

Confusing relationship between `has_headers` and `set_headers`

Open
#275 14 comments 0 reactions 0 assignees View on GitHub
doc
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?

csv = "1.1.6"

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

The header line is parsed as the rest of the lines, when it should not be parsed. This results in failure when the column names are parsed and validated with serde.

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

I need to use the following workaround to make it work:

```
pub fn my_deser<'de, D>(deserializer: D) -> Result
where
D: serde::Deserializer<'de>,
{
let raw: String = serde::Deserialize::deserialize(deserializer)?;
println!("{}", &raw);
Ok(MyFieldType::create_instance())
}

#[derive(Serialize, Deserialize, Default, Debug)]
struct MyEntry {
#[serde(deserialize_with = "my_deser", alias = "aaaa")]
meaningful_name: MyFieldType,
}

fn parse_csv(bytes_reader: &[u8]) -> anyhow::Result> {
// Skip the first line containing the headers to workaround the CSV reader
// failing to ignore the first line despite has_headers(true).
let first_newline = bytes_reader.iter().position(|&c| c == b'\n').unwrap();
let bytes_reader: &[u8] = &bytes_reader[first_newline..];
let mut reader = ReaderBuilder::new()
.has_headers(true)
.flexible(true)
.delimiter(b',')
.quoting(true)
.quote(b'"')
.trim(Trim::All)
.from_reader(bytes_reader);
reader.set_headers(csv::StringRecord::from(
&[
// Note we can't use a meaningful name here because this column name
// is parsed as a value.
"aaaa",
][..],
));
reader
.into_deserialize()
.map(|e| match e {
Ok(entry) => Ok(entry),
Err(err) => Err(anyhow::anyhow!("Failed deserializing row: {:#?}", err)),
})
.collect::, _>>()
}
```

This is the CSV:
```
"name"
"000000"
```

Does not matter that `has_headers` is set to `true` or `false`, seems broken.

Also, note if I'm not manually skipping the first line, `"name"` is also parsed despite using `set_headers()` and despite `has_headers(true)`, seems a different issue?

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the ReaderBuilder options has_headers and set_headers, then trace how into_deserialize consumes records using the minimal CSV example in the issue. Verify whether the header row is deserialized and clarify or correct the interaction so the observed behavior matches the documented contract.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
data
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.