use crate::pc_errors::*;
use csv::Reader;
use flate2::read::GzDecoder;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use crate::label_sources::*;
pub fn open_int_csv<P: AsRef<Path> + std::fmt::Debug>(
path: &P,
index: usize,
) -> PointCloudResult<SmallIntLabels> {
if !path.as_ref().exists() {
panic!("CSV file {:?} does not exist", path);
}
match File::open(&path) {
Ok(file) => {
if path.as_ref().extension().unwrap() == "gz" {
read_csv(index, path, Reader::from_reader(GzDecoder::new(file)))
} else {
read_csv(index, path, Reader::from_reader(file))
}
}
Err(e) => panic!("Unable to open csv file {:#?}", e),
}
}
fn read_csv<P: AsRef<Path> + std::fmt::Debug, R: Read>(
index: usize,
path: &P,
mut rdr: Reader<R>,
) -> PointCloudResult<SmallIntLabels> {
let mut labels = Vec::new();
let mut mask = Vec::new();
for result in rdr.records() {
let record = result.expect("Unable to read a record from the label CSV");
match record.get(index) {
Some(val) => {
let val = val.parse::<i64>().map_err(|_| {
PointCloudError::ParsingError(ParsingError::CSVReadError {
file_name: path.as_ref().to_string_lossy().to_string(),
line_number: record.position().unwrap().line() as usize,
key: format!("Unable to read u64 from {:?}", record),
})
})?;
if 0 < val {
mask.push(true);
} else {
mask.push(false);
}
labels.push(val);
}
None => {
labels.push(0);
mask.push(false);
}
}
}
if mask.iter().any(|f| !f) {
Ok(SmallIntLabels::new(labels, Some(mask)))
} else {
Ok(SmallIntLabels::new(labels, None))
}
}