use csv::ReaderBuilder; use std::{fs::File, path::Path}; pub struct OPERABitmap { bitmap: Vec, } impl OPERABitmap { pub fn load>(p: P) -> anyhow::Result { let mut rdr = ReaderBuilder::new() .has_headers(false) .delimiter(b';') .from_reader(File::open(p)?); let mut results = default_bitmap(); let mut line: usize = 0; for result in rdr.records() { let record = result?; let parse_field = |idx: usize| { record .get(idx) .map(|s| s.trim().to_string()) .ok_or_else(|| { anyhow::anyhow!("Parse Opera Bitmap File failed at index {}", idx) }) }; let f = parse_field(0)?.parse()?; let x = parse_field(1)?.parse()?; let y = parse_field(2)?.parse()?; let dw = parse_field(3)?.parse()?; let entry = OPERABitmapEntry { f, x, y, datawidth_bits: dw, }; if let Some(line) = results.get_mut(line) { *line = entry; } else { results.push(entry); } line += 1; } Ok(OPERABitmap { bitmap: results }) } } pub struct OPERABitmapEntry { pub f: u16, pub x: u16, pub y: u16, pub datawidth_bits: u8, } fn default_bitmap() -> Vec { const VALUES: [(u16, u16, u16, u8); 8] = [ (3, 21, 192, 1), (3, 21, 193, 1), (3, 21, 194, 1), (3, 21, 195, 1), (3, 21, 196, 1), (3, 21, 197, 1), (3, 21, 200, 2), (3, 21, 202, 2), ]; VALUES .iter() .map(|(f, x, y, dw)| OPERABitmapEntry { f: *f, x: *x, y: *y, datawidth_bits: *dw, }) .collect() }