csv/
cookbook.rs

1/*!
2A cookbook of examples for CSV reading and writing.
3
4# List of examples
5
6This is a list of examples that follow. Each of them can be found in the
7`examples` directory of the
8[`rust-csv`](https://github.com/BurntSushi/rust-csv)
9repository.
10
11For **reading** CSV:
12
131. [Basic](#reading-basic)
142. [With Serde](#reading-with-serde)
153. [Setting a different delimiter](#reading-setting-a-different-delimiter)
164. [Without headers](#reading-without-headers)
17
18For **writing** CSV:
19
205. [Basic](#writing-basic)
216. [With Serde](#writing-with-serde)
22
23Please
24[submit a pull request](https://github.com/BurntSushi/rust-csv/pulls)
25if you're interested in adding an example to this list!
26
27# Reading: basic
28
29This example shows how to read CSV data from stdin and print each record to
30stdout.
31
32```no_run
33# //cookbook-read-basic.rs
34use std::{error::Error, io, process};
35
36fn example() -> Result<(), Box<dyn Error>> {
37    // Build the CSV reader and iterate over each record.
38    let mut rdr = csv::Reader::from_reader(io::stdin());
39    for result in rdr.records() {
40        // The iterator yields Result<StringRecord, Error>, so we check the
41        // error here..
42        let record = result?;
43        println!("{:?}", record);
44    }
45    Ok(())
46}
47
48fn main() {
49    if let Err(err) = example() {
50        println!("error running example: {}", err);
51        process::exit(1);
52    }
53}
54```
55
56The above example can be run like so:
57
58```ignore
59$ git clone git://github.com/BurntSushi/rust-csv
60$ cd rust-csv
61$ cargo run --example cookbook-read-basic < examples/data/smallpop.csv
62```
63
64# Reading: with Serde
65
66This is like the previous example, except it shows how to deserialize each
67record into a struct type that you define.
68
69For more examples and details on how Serde deserialization works, see the
70[`Reader::deserialize`](../struct.Reader.html#method.deserialize)
71method.
72
73```no_run
74# //cookbook-read-serde.rs
75# #![allow(dead_code)]
76use std::{error::Error, io, process};
77
78use serde::Deserialize;
79
80// By default, struct field names are deserialized based on the position of
81// a corresponding field in the CSV data's header record.
82#[derive(Debug, Deserialize)]
83struct Record {
84    city: String,
85    region: String,
86    country: String,
87    population: Option<u64>,
88}
89
90fn example() -> Result<(), Box<dyn Error>> {
91    let mut rdr = csv::Reader::from_reader(io::stdin());
92    for result in rdr.deserialize() {
93        // Notice that we need to provide a type hint for automatic
94        // deserialization.
95        let record: Record = result?;
96        println!("{:?}", record);
97    }
98    Ok(())
99}
100
101fn main() {
102    if let Err(err) = example() {
103        println!("error running example: {}", err);
104        process::exit(1);
105    }
106}
107```
108
109The above example can be run like so:
110
111```ignore
112$ git clone git://github.com/BurntSushi/rust-csv
113$ cd rust-csv
114$ cargo run --example cookbook-read-serde < examples/data/smallpop.csv
115```
116
117# Reading: setting a different delimiter
118
119This example shows how to read CSV data from stdin where fields are separated
120by `:` instead of `,`.
121
122```no_run
123# //cookbook-read-colon.rs
124use std::{error::Error, io, process};
125
126fn example() -> Result<(), Box<dyn Error>> {
127    let mut rdr = csv::ReaderBuilder::new()
128        .delimiter(b':')
129        .from_reader(io::stdin());
130    for result in rdr.records() {
131        let record = result?;
132        println!("{:?}", record);
133    }
134    Ok(())
135}
136
137fn main() {
138    if let Err(err) = example() {
139        println!("error running example: {}", err);
140        process::exit(1);
141    }
142}
143```
144
145The above example can be run like so:
146
147```ignore
148$ git clone git://github.com/BurntSushi/rust-csv
149$ cd rust-csv
150$ cargo run --example cookbook-read-colon < examples/data/smallpop-colon.csv
151```
152
153# Reading: without headers
154
155The CSV reader in this crate assumes that CSV data has a header record by
156default, but the setting can be toggled. When enabled, the first record in
157CSV data in interpreted as the header record and is skipped. When disabled, the
158first record is not skipped. This example shows how to disable that setting.
159
160```no_run
161# //cookbook-read-no-headers.rs
162use std::{error::Error, io, process};
163
164fn example() -> Result<(), Box<dyn Error>> {
165    let mut rdr = csv::ReaderBuilder::new()
166        .has_headers(false)
167        .from_reader(io::stdin());
168    for result in rdr.records() {
169        let record = result?;
170        println!("{:?}", record);
171    }
172    Ok(())
173}
174
175fn main() {
176    if let Err(err) = example() {
177        println!("error running example: {}", err);
178        process::exit(1);
179    }
180}
181```
182
183The above example can be run like so:
184
185```ignore
186$ git clone git://github.com/BurntSushi/rust-csv
187$ cd rust-csv
188$ cargo run --example cookbook-read-no-headers < examples/data/smallpop-no-headers.csv
189```
190
191# Writing: basic
192
193This example shows how to write CSV data to stdout.
194
195```no_run
196# //cookbook-write-basic.rs
197use std::{error::Error, io, process};
198
199fn example() -> Result<(), Box<dyn Error>> {
200    let mut wtr = csv::Writer::from_writer(io::stdout());
201
202    // When writing records without Serde, the header record is written just
203    // like any other record.
204    wtr.write_record(&["city", "region", "country", "population"])?;
205    wtr.write_record(&["Southborough", "MA", "United States", "9686"])?;
206    wtr.write_record(&["Northbridge", "MA", "United States", "14061"])?;
207    wtr.flush()?;
208    Ok(())
209}
210
211fn main() {
212    if let Err(err) = example() {
213        println!("error running example: {}", err);
214        process::exit(1);
215    }
216}
217```
218
219The above example can be run like so:
220
221```ignore
222$ git clone git://github.com/BurntSushi/rust-csv
223$ cd rust-csv
224$ cargo run --example cookbook-write-basic > /tmp/simplepop.csv
225```
226
227# Writing: with Serde
228
229This example shows how to write CSV data to stdout with Serde. Namely, we
230represent each record using a custom struct that we define. In this example,
231headers are written automatically.
232
233```no_run
234# //cookbook-write-serde.rs
235use std::{error::Error, io, process};
236
237use serde::Serialize;
238
239#[derive(Debug, Serialize)]
240struct Record {
241    city: String,
242    region: String,
243    country: String,
244    population: Option<u64>,
245}
246
247fn example() -> Result<(), Box<dyn Error>> {
248    let mut wtr = csv::Writer::from_writer(io::stdout());
249
250    // When writing records with Serde using structs, the header row is written
251    // automatically.
252    wtr.serialize(Record {
253        city: "Southborough".to_string(),
254        region: "MA".to_string(),
255        country: "United States".to_string(),
256        population: Some(9686),
257    })?;
258    wtr.serialize(Record {
259        city: "Northbridge".to_string(),
260        region: "MA".to_string(),
261        country: "United States".to_string(),
262        population: Some(14061),
263    })?;
264    wtr.flush()?;
265    Ok(())
266}
267
268fn main() {
269    if let Err(err) = example() {
270        println!("error running example: {}", err);
271        process::exit(1);
272    }
273}
274```
275
276The above example can be run like so:
277
278```ignore
279$ git clone git://github.com/BurntSushi/rust-csv
280$ cd rust-csv
281$ cargo run --example cookbook-write-serde > /tmp/simplepop.csv
282```
283*/