Movatterモバイル変換


[0]ホーム

URL:


Rust Cookbook

    CSV processing

    Read CSV records

    csv-badgecat-encoding-badge

    Reads standard CSV records intocsv::StringRecord — a weakly typeddata representation which expects valid UTF-8 rows. Alternatively,csv::ByteRecord makes no assumptions about UTF-8.

    use csv::Error;fn main() -> Result<(), Error> {    let csv = "year,make,model,description1948,Porsche,356,Luxury sports car1967,Ford,Mustang fastback 1967,American car";    let mut reader = csv::Reader::from_reader(csv.as_bytes());    for record in reader.records() {        let record = record?;        println!(            "In {}, {} built the {} model. It is a {}.",            &record[0],            &record[1],            &record[2],            &record[3]        );    }    Ok(())}

    Serde deserializes data into strongly type structures. See thecsv::Reader::deserialize method.

    use serde::Deserialize;#[derive(Deserialize)]struct Record {    year: u16,    make: String,    model: String,    description: String,}fn main() -> Result<(), csv::Error> {    let csv = "year,make,model,description1948,Porsche,356,Luxury sports car1967,Ford,Mustang fastback 1967,American car";    let mut reader = csv::Reader::from_reader(csv.as_bytes());    for record in reader.deserialize() {        let record: Record = record?;        println!(            "In {}, {} built the {} model. It is a {}.",            record.year,            record.make,            record.model,            record.description        );    }    Ok(())}

    Read CSV records with different delimiter

    csv-badgecat-encoding-badge

    Reads CSV records with a tab [delimiter].

    use csv::Error;use serde::Deserialize;#[derive(Debug, Deserialize)]struct Record {    name: String,    place: String,    #[serde(deserialize_with = "csv::invalid_option")]    id: Option<u64>,}use csv::ReaderBuilder;fn main() -> Result<(), Error> {    let data = "name\tplace\tid\n\        Mark\tMelbourne\t46\n\        Ashley\tZurich\t92";    let mut reader = ReaderBuilder::new().delimiter(b'\t').from_reader(data.as_bytes());    for result in reader.deserialize::<Record>() {        println!("{:?}", result?);    }    Ok(())}

    Filter CSV records matching a predicate

    csv-badgecat-encoding-badge

    Returnsonly the rows fromdata with a field that matchesquery.

    use anyhow::Result;use std::io;fn main() -> Result<()> {    let query = "CA";    let data = "\City,State,Population,Latitude,LongitudeKenai,AK,7610,60.5544444,-151.2583333Oakman,AL,,33.7133333,-87.3886111Sandfort,AL,,32.3380556,-85.2233333West Hollywood,CA,37031,34.0900000,-118.3608333";    let mut rdr = csv::ReaderBuilder::new().from_reader(data.as_bytes());    let mut wtr = csv::Writer::from_writer(io::stdout());    wtr.write_record(rdr.headers()?)?;    for result in rdr.records() {        let record = result?;        if record.iter().any(|field| field == query) {            wtr.write_record(&record)?;        }    }    wtr.flush()?;    Ok(())}

    Disclaimer: this example has been adapted fromthe csv crate tutorial.

    Handle invalid CSV data with Serde

    csv-badgeserde-badgecat-encoding-badge

    CSV files often contain invalid data. For these cases, thecsv crateprovides a custom deserializer,csv::invalid_option, which automaticallyconverts invalid data to None values.

    use csv::Error;use serde::Deserialize;#[derive(Debug, Deserialize)]struct Record {    name: String,    place: String,    #[serde(deserialize_with = "csv::invalid_option")]    id: Option<u64>,}fn main() -> Result<(), Error> {    let data = "name,place,idmark,sydney,46.5ashley,zurich,92akshat,delhi,37alisha,colombo,xyz";    let mut rdr = csv::Reader::from_reader(data.as_bytes());    for result in rdr.deserialize() {        let record: Record = result?;        println!("{:?}", record);    }    Ok(())}

    Serialize records to CSV

    csv-badgecat-encoding-badge

    This example shows how to serialize a Rust tuple.csv::writer supports automaticserialization from Rust types into CSV records.write_record writesa simple record containing string data only. Data with more complex valuessuch as numbers, floats, and options useserialize. Since CSVwriter uses internal buffer, always explicitlyflush when done.

    use anyhow::Result;use std::io;fn main() -> Result<()> {    let mut wtr = csv::Writer::from_writer(io::stdout());    wtr.write_record(&["Name", "Place", "ID"])?;    wtr.serialize(("Mark", "Sydney", 87))?;    wtr.serialize(("Ashley", "Dublin", 32))?;    wtr.serialize(("Akshat", "Delhi", 11))?;    wtr.flush()?;    Ok(())}

    Serialize records to CSV using Serde

    csv-badgeserde-badgecat-encoding-badge

    The following example shows how to serialize custom structs as CSV records usingtheserde crate.

    use anyhow::Result;use serde::Serialize;use std::io;#[derive(Serialize)]struct Record<'a> {    name: &'a str,    place: &'a str,    id: u64,}fn main() -> Result<()> {    let mut wtr = csv::Writer::from_writer(io::stdout());    let rec1 = Record { name: "Mark", place: "Melbourne", id: 56};    let rec2 = Record { name: "Ashley", place: "Sydney", id: 64};    let rec3 = Record { name: "Akshat", place: "Delhi", id: 98};    wtr.serialize(rec1)?;    wtr.serialize(rec2)?;    wtr.serialize(rec3)?;    wtr.flush()?;    Ok(())}# Transform CSV column[![csv-badge]][csv] [![serde-badge]][serde] [![cat-encoding-badge]][cat-encoding]Transform a CSV file containing a color name and a hex color into one with acolor name and an rgb color.  Utilizes the [csv] crate to read and write thecsv file, and [serde] to deserialize and serialize the rows to and from bytes.See [csv::Reader::deserialize], [serde::Deserialize], and [std::str::FromStr]```rust,edition2018use anyhow::{Result, anyhow};use csv::{Reader, Writer};use serde::{de, Deserialize, Deserializer};use std::str::FromStr;#[derive(Debug)]struct HexColor {    red: u8,    green: u8,    blue: u8,}#[derive(Debug, Deserialize)]struct Row {    color_name: String,    color: HexColor,}impl FromStr for HexColor {    type Err = anyhow::Error;    fn from_str(hex_color: &str) -> std::result::Result<Self, Self::Err> {        let trimmed = hex_color.trim_matches('#');        if trimmed.len() != 6 {            Err(anyhow!("Invalid length of hex string"))        } else {            Ok(HexColor {                red: u8::from_str_radix(&trimmed[..2], 16)?,                green: u8::from_str_radix(&trimmed[2..4], 16)?,                blue: u8::from_str_radix(&trimmed[4..6], 16)?,            })        }    }}impl<'de> Deserialize<'de> for HexColor {    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>    where        D: Deserializer<'de>,    {        let s = String::deserialize(deserializer)?;        FromStr::from_str(&s).map_err(de::Error::custom)    }}fn main() -> Result<()> {    let data = "color_name,colorred,#ff0000green,#00ff00blue,#0000FFperiwinkle,#ccccffmagenta,#ff00ff"        .to_owned();    let mut out = Writer::from_writer(vec![]);    let mut reader = Reader::from_reader(data.as_bytes());    for result in reader.deserialize::<Row>() {        let res = result?;        out.serialize((            res.color_name,            res.color.red,            res.color.green,            res.color.blue,        ))?;    }    let written = String::from_utf8(out.into_inner()?)?;    assert_eq!(Some("magenta,255,0,255"), written.lines().last());    println!("{}", written);    Ok(())}

    [8]ページ先頭

    ©2009-2025 Movatter.jp