J'utilise le csv
y serde
pour désérialiser les fichiers csv. Le problème est que le dernier champ est en fait une liste séparée par des virgules.
field1,field2,field3
xx, xx, str1, ..., strN
xx, xx,
xx, xx, str1, ..., strM
Et voici comment cela fonctionne en Rust, en le lisant avec .flexible(true)
sur le lecteur :
#[derive(Debug, Deserialize)]
struct Row {
field1: isize,
field2: isize,
field3: Vec<String>,
}
Tout fonctionne bien si le CSV a le ,field3
la ligne d'en-tête. Mais certains des fichiers ne l'ont pas, et je ne trouve pas de solution pour que Serde remplisse toujours la ligne d'en-tête. Vec
. Tout ce que j'ai pu faire, c'est #[serde(default)]
qui laisse juste field3
vide.
Ici une rouille terrain de jeu montrant le problème :
extern crate csv;
#[macro_use]
extern crate serde_derive;
#[derive(Debug, Deserialize)]
struct Row {
field1: String,
field2: String,
#[serde(default)]
field3: Vec<String>,
}
fn test(str: String) {
let mut reader = csv::ReaderBuilder::new()
.flexible(true)
.from_reader(str.as_bytes());
for row in reader.deserialize() {
if let Ok(row) = row {
let row: Row = row;
println!("{:?}", row);
}
}
}
fn main() {
let csv_data = "
field1,field2,field3
xx,yy,one,two,three
zz,ww,
aa,bb
cc,dd,foo,bar,ban
";
println!("With full header");
test(csv_data.to_string());
let csv_alt_data = "
field1,field2
xx,yy,one,two,three
zz,ww,
aa,bb
cc,dd,foo,bar,ban
";
println!("With incomplet header");
test(csv_alt_data.to_string());
}