I'm trying to read a CSV file using the CSV crate and lazily cast all its cells to f64:
use csv::ReaderBuilder; // 1.1.4
fn get_df_iterator(path: &str) {
// Build the CSV reader and iterate over each record casting to f64
let rdr = ReaderBuilder::new()
.delimiter(b'\t')
.from_path(path)
.unwrap();
rdr.into_records().map(|record_result| {
record_result
.unwrap()
.into_iter()
.map(|cell: &str| cell.parse::<f64>().unwrap())
})
}
fn main() {
let m1 = get_df_iterator("df1.csv");
}
I've read that to return types with closures in stable Rust we can use Boxes. I've tried with:
use csv::{Error, ReaderBuilder, StringRecord};
fn get_df_iterator_box(path: &str) -> Box<dyn Iterator<Item = Box<dyn Iterator<Item = f64>>>> {
// Build the CSV reader and iterate over each record.
let rdr = ReaderBuilder::new()
.delimiter(b'\t')
.from_path(path)
.unwrap();
// Returns Box<Iterator<Item = f64>>
let parse_str = |cell: &str| cell.parse::<f64>().unwrap();
let parse_record = |record_result: Result<StringRecord, Error>| {
Box::new(record_result.unwrap().into_iter().map(parse_str))
};
// Box<Iterator<Item = Box<Iterator<Item = f64>>>>
Box::new(rdr.into_records().map(parse_record))
}
fn main() {
let m1 = get_df_iterator_box("df1.csv");
}
error[E0271]: type mismatch resolving `<[closure@src/main.rs:13:24: 15:6] as FnOnce<(std::result::Result<StringRecord, csv::Error>,)>>::Output == Box<(dyn Iterator<Item = f64> + 'static)>`
--> src/main.rs:18:5
|
11 | let parse_str = |cell: &str| cell.parse::<f64>().unwrap();
| ----------------------------------------- the expected closure
...
18 | Box::new(rdr.into_records().map(parse_record))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Map`, found trait object `dyn Iterator`
|
= note: expected struct `Box<Map<StringRecordIter<'_>, [closure@src/main.rs:11:21: 11:62]>>`
found struct `Box<(dyn Iterator<Item = f64> + 'static)>`
= note: required because of the requirements on the impl of `Iterator` for `Map<StringRecordsIntoIter<File>, [closure@src/main.rs:13:24: 15:6]>`
= note: required for the cast to the object type `dyn Iterator<Item = Box<(dyn Iterator<Item = f64> + 'static)>>`
I don't understand what the problem is. It's supposed to return a Box which contains an iterator that returns Boxes of iterators of f64. Here there's another playground with that update! If you want to replicate with the same file I'm using here you can download it.