I'm trying to encapsulate a CSV iterator into one of my structs like this:
struct PopulationCount {
city: String,
country: String,
count: u64,
}
struct PopulationIter<'a> {
reader: csv::Reader<std::fs::File>,
records: DecodedRecords<'a, std::fs::File, Row>,
}
impl<'a> PopulationIter<'a> {
fn new(file_path: &str, country: &str) -> Result<PopulationIter<'a>, Box<Error>> {
let file = File::open(file_path)?;
let mut reader = csv::Reader::from_reader(file);
let decoded_records = reader.decode::<Row>();
Ok(PopulationIter {
reader: reader,
records: decoded_records,
})
}
}
impl<'a> Iterator for PopulationIter<'a> {
type Item = csv::Result<Row>;
fn next(&mut self) -> Option<Self::Item> {
self.records.next()
}
}
As far as I understand, DecodedRecords
holds a reference to the csv::Reader
, that's why the csv::Reader
must live as long as the DecodedRecords
.
Trying to compile this code gives me this error:
error: `reader` does not live long enough
--> src/main.rs:39:31
|
39 | let decoded_records = reader.decode::<Row>();
| ^^^^^^ does not live long enough
...
42 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the block at 34:85...
--> src/main.rs:34:86
|
34 | fn new(file_path: &str, country: &str) -> Result<PopulationIter<'a>, Box<Error>> {
| ^
I don't understand this since the reader is passed to the PopulationIter
struct, I would think move semantics would apply, making reader
live as long as the struct. This is obviously not what happens here.