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