青蛙小白
目录

csv

一个快速且灵活的Rust CSV读写器,支持Serde序列化。

cargo add csv

快速示例

这个示例展示了如何从标准输入读取CSV数据并将每条记录打印到标准输出。

use std::{error::Error, io, process};

fn example() -> Result<(), Box<dyn Error>> {
    // Build the CSV reader and iterate over each record.
    let mut rdr = csv::Reader::from_reader(io::stdin());
    let headers: &csv::StringRecord = rdr.headers()?;
    println!("{:?}", headers);
    for result in rdr.records() {
        // The iterator yields Result<StringRecord, Error>, so we check the
        // error here.
        let record: csv::StringRecord = result?;
        println!("{:?}", record);
    }
    Ok(())
}

fn main() {
    if let Err(err) = example() {
        println!("error running example: {}", err);
        process::exit(1);
    }
}
cargo run < ./data/example.csv

使用Serde的示例

本示例展示如何将CSV数据从标准输入读取到自定义的结构体中。默认情况下,结构体的成员名称会与CSV数据的标题记录中的值相匹配。

use std::{error::Error, io, process};

#[derive(Debug, serde::Deserialize)]
#[serde(rename_all = "camelCase")] // https://serde.rs/container-attrs.html
struct Record {
    city: String,
    region: String,
    country: String,
    #[serde(rename = "population")]
    population: Option<u64>,
}

fn example() -> Result<(), Box<dyn Error>> {
    let mut rdr = csv::Reader::from_reader(io::stdin());
    for result in rdr.deserialize() {
        // Notice that we need to provide a type hint for automatic
        // deserialization.
        let record: Record = result?;
        println!("{:?}", record);
    }
    Ok(())
}

fn main() {
    if let Err(err) = example() {
        println!("error running example: {}", err);
        process::exit(1);
    }
}
cargo run < ./data/smallpop.csv
评论