• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*!
2 A cookbook of examples for CSV reading and writing.
3 
4 # List of examples
5 
6 This 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)
9 repository.
10 
11 For **reading** CSV:
12 
13 1. [Basic](#reading-basic)
14 2. [With Serde](#reading-with-serde)
15 3. [Setting a different delimiter](#reading-setting-a-different-delimiter)
16 4. [Without headers](#reading-without-headers)
17 
18 For **writing** CSV:
19 
20 5. [Basic](#writing-basic)
21 6. [With Serde](#writing-with-serde)
22 
23 Please
24 [submit a pull request](https://github.com/BurntSushi/rust-csv/pulls)
25 if you're interested in adding an example to this list!
26 
27 # Reading: basic
28 
29 This example shows how to read CSV data from stdin and print each record to
30 stdout.
31 
32 ```no_run
33 # //cookbook-read-basic.rs
34 use std::{error::Error, io, process};
35 
36 fn 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 
48 fn main() {
49     if let Err(err) = example() {
50         println!("error running example: {}", err);
51         process::exit(1);
52     }
53 }
54 ```
55 
56 The 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 
66 This is like the previous example, except it shows how to deserialize each
67 record into a struct type that you define.
68 
69 For more examples and details on how Serde deserialization works, see the
70 [`Reader::deserialize`](../struct.Reader.html#method.deserialize)
71 method.
72 
73 ```no_run
74 # //cookbook-read-serde.rs
75 # #![allow(dead_code)]
76 use std::{error::Error, io, process};
77 
78 use 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)]
83 struct Record {
84     city: String,
85     region: String,
86     country: String,
87     population: Option<u64>,
88 }
89 
90 fn 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 
101 fn main() {
102     if let Err(err) = example() {
103         println!("error running example: {}", err);
104         process::exit(1);
105     }
106 }
107 ```
108 
109 The 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 
119 This example shows how to read CSV data from stdin where fields are separated
120 by `:` instead of `,`.
121 
122 ```no_run
123 # //cookbook-read-colon.rs
124 use std::{error::Error, io, process};
125 
126 fn 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 
137 fn main() {
138     if let Err(err) = example() {
139         println!("error running example: {}", err);
140         process::exit(1);
141     }
142 }
143 ```
144 
145 The 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 
155 The CSV reader in this crate assumes that CSV data has a header record by
156 default, but the setting can be toggled. When enabled, the first record in
157 CSV data in interpreted as the header record and is skipped. When disabled, the
158 first record is not skipped. This example shows how to disable that setting.
159 
160 ```no_run
161 # //cookbook-read-no-headers.rs
162 use std::{error::Error, io, process};
163 
164 fn 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 
175 fn main() {
176     if let Err(err) = example() {
177         println!("error running example: {}", err);
178         process::exit(1);
179     }
180 }
181 ```
182 
183 The 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 
193 This example shows how to write CSV data to stdout.
194 
195 ```no_run
196 # //cookbook-write-basic.rs
197 use std::{error::Error, io, process};
198 
199 fn 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 
211 fn main() {
212     if let Err(err) = example() {
213         println!("error running example: {}", err);
214         process::exit(1);
215     }
216 }
217 ```
218 
219 The 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 
229 This example shows how to write CSV data to stdout with Serde. Namely, we
230 represent each record using a custom struct that we define. In this example,
231 headers are written automatically.
232 
233 ```no_run
234 # //cookbook-write-serde.rs
235 use std::{error::Error, io, process};
236 
237 use serde::Serialize;
238 
239 #[derive(Debug, Serialize)]
240 struct Record {
241     city: String,
242     region: String,
243     country: String,
244     population: Option<u64>,
245 }
246 
247 fn 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 
268 fn main() {
269     if let Err(err) = example() {
270         println!("error running example: {}", err);
271         process::exit(1);
272     }
273 }
274 ```
275 
276 The 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 */
284