83 lines
2.0 KiB
Rust
83 lines
2.0 KiB
Rust
use csv::ReaderBuilder;
|
|
use std::{fs::File, path::Path};
|
|
|
|
pub struct OPERABitmap {
|
|
bitmap: Vec<OPERABitmapEntry>,
|
|
}
|
|
|
|
impl OPERABitmap {
|
|
pub fn load<P: AsRef<Path>>(p: P) -> anyhow::Result<Self> {
|
|
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<OPERABitmapEntry> {
|
|
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()
|
|
}
|