//@ known-bug: #90110 use std::fs::File; use std::io::{BufReader, BufRead}; use std::str::Split; use std::path::Path; pub trait Parser where dyn Parser: Sized { fn new(split_header: Split<&str>) -> Self where Self: Sized; fn parse_line(&self, split_line: &Split<&str>) -> D; } pub struct CsvReader { parser: Box>, reader: BufReader, buf: String, // Buffer we will read into. Avoids re-allocation on each line. path: String, // Record this so we can return more informative error messages. line: usize, // Same motivation for this. } impl CsvReader where dyn Parser: Sized { fn new(path: &str, make_parser: F) -> CsvReader where F: Fn(Split) -> dyn Parser { let file = match File::open(Path::new(path)) { Err(err) => panic!("Couldn't read {}: {}", path, err), Ok(file) => file, }; let mut reader = BufReader::new(file); let mut buf = String::new(); let parser = Box::new(match reader.read_line(&mut buf) { Err(err) => panic!("Failed to read the header line from {}: {}", path, err), Ok(_) => { let split_header = buf.split(','); make_parser(split_header) }, }); CsvReader { parser: parser, reader, buf, path: path.to_string(), line: 2, } } } pub fn main() {}