Ben Chuanlong Du's Blog

It is never too late to learn.

Read and Write CSV Files in Rust

Things on this page are fragmentary and immature notes/thoughts of the author. Please read with your own judgement!

Tips and Traps

  1. By defaut, csv::Reader requires headers.

  2. When the csv crate is used together with the serde crate for deserialization, CSV files to be parsed have to be strictly well formatted. For example, the headers in CSV files have to match the defintion in the serde struct. Otherwise, the code will panic with an error of "missing fields".

In [2]:
:dep csv = "1.2.2"
In [3]:
:dep serde = { version = "1.0.166", features = ["derive"] }
In [4]:
use std::fs::File;
use std::io;
use std::io::Write;
use serde::Deserialize;

With Serde

In [11]:
pub fn read_r1_csv(file: &str) {
    #[derive(Debug, Deserialize)]
    struct Record {
        pub five_cards: String,
        pub other_known_cards: String,
        pub bust_factor: f64,
        pub num_sim1: usize,
        pub num_sim2: usize,
        pub num_sim3: usize,
        pub num_sim4: usize,
    }
    let mut csv_reader = {
        let file = File::open(file).unwrap_or_else(|_| panic!("The file {file} does not exist!"));
        csv::Reader::from_reader(file)
    };
    csv_reader.deserialize().for_each(|r| {
        let r: Record = r.unwrap();
        println!("five_cards: \"{}\", other_known_cards: \"{}\", bust_factor: {}, num_sim1: {}, num_sim2: {}, num_sim3: {}, num_sim4: {}", 
            r.five_cards, 
            r.other_known_cards,
            r.bust_factor,
            r.num_sim1,
            r.num_sim2,
            r.num_sim3,
            r.num_sim4,
        );
    });
}

read_r1_csv("r1.csv")
five_cards: "5s 5h 5c 5d As", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Qs Qh Qc Qd 3d", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ks Kh Kc Kd 4h", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "As Ah Ac Ad 6c", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "3s Th 3c Td Ts", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Qs 9s 8s 4s 3s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "As 9s 8s 4s 3s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ts Th Tc 7d 7s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "4s 5h 6c 7d 8s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "As 2c 3d 4s 5h", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "As Kc Qd Js Th", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ts Th Tc Ad 3s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ts Th Tc Ad 3d", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ts Th Tc 4d 3s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "As Ah 8c 8d 9s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Qs Qh 8c 8d 9s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ts Th 8c 8d 9s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
Out[11]:
()
In [11]:
pub fn read_r1_csv(file: &str) {
    #[derive(Debug, Deserialize)]
    struct Record {
        pub five_cards: String,
        pub other_known_cards: String,
        pub bust_factor: f64,
        pub num_sim1: usize,
        pub num_sim2: usize,
        pub num_sim3: usize,
        pub num_sim4: usize,
    }
    let mut csv_reader = {
        let file = File::open(file).unwrap_or_else(|_| panic!("The file {file} does not exist!"));
        csv::Reader::from_reader(file)
    };
    csv_reader.deserialize().for_each(|r| {
        let r: Record = r.unwrap();
        println!("five_cards: \"{}\", other_known_cards: \"{}\", bust_factor: {}, num_sim1: {}, num_sim2: {}, num_sim3: {}, num_sim4: {}", 
            r.five_cards, 
            r.other_known_cards,
            r.bust_factor,
            r.num_sim1,
            r.num_sim2,
            r.num_sim3,
            r.num_sim4,
        );
    });
}

read_r1_csv("r1.csv")
five_cards: "5s 5h 5c 5d As", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Qs Qh Qc Qd 3d", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ks Kh Kc Kd 4h", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "As Ah Ac Ad 6c", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "3s Th 3c Td Ts", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Qs 9s 8s 4s 3s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "As 9s 8s 4s 3s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ts Th Tc 7d 7s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "4s 5h 6c 7d 8s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "As 2c 3d 4s 5h", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "As Kc Qd Js Th", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ts Th Tc Ad 3s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ts Th Tc Ad 3d", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ts Th Tc 4d 3s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "As Ah 8c 8d 9s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Qs Qh 8c 8d 9s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
five_cards: "Ts Th 8c 8d 9s", other_known_cards: "", bust_factor: 2, num_sim1: 20, num_sim2: 20, num_sim3: 20, num_sim4: 20
Out[11]:
()

References

In [ ]:

Comments