当标题行中可能没有最后一个列名时,使用Serde反序列化CSV

时间:2019-04-09 22:15:43

标签: csv rust serde

我正在使用csvserde条板箱反序列化csv文件。关键是最后一个字段实际上是一个用逗号分隔的列表。

field1,field2,field3
xx, xx, str1, ..., strN
xx, xx,
xx, xx, str1, ..., strM

这就是它在Rust中的映射方式,并在阅读器上用.flexible(true)进行阅读:

#[derive(Debug, Deserialize)]
struct Row {
  field1: isize,
  field2: isize,
  field3: Vec<String>,
}

如果CSV的标题行为,field3,则一切正常。但是某些文件没有它,我找不到解决方案让Serde仍然填充Vec。我所能做的就是#[serde(default)],只是让field3为空。

出现锈迹playground,表明问题所在:

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());
}

1 个答案:

答案 0 :(得分:3)

使用headers()set_headers(),在读取的行应添加之前手工添加字段标题:

writer.writeRow(dataString)
 writer.close()

但是,那又快又脏。