use std::fs::File;
use std::io::{BufRead,BufReader};
use std::str::FromStr;
use std::fmt::Debug;
pub struct TestVector<TIn, TOut> {
pub inp: Vec<TIn>,
pub out: TOut
}
pub fn load_test_file<TIn, TOut>(file: &str) -> Vec<TestVector::<TIn, TOut>>
where
TIn : FromStr + Debug,
TIn::Err: Debug,
TOut : FromStr + Debug,
TOut::Err: Debug,
{
let mut vectors: Vec<TestVector::<TIn, TOut>> = vec![];
let file = File::open(file).expect("Could not read test data!");
let reader = BufReader::new(file);
for (_, line) in reader.lines().enumerate() {
let line = line.expect("Could not read a line!");
if line.starts_with('#') || line.len() == 0 {
continue;
}
let (inp_str, out_str) = line.split_once(":").unwrap();
let out: TOut = out_str.trim().parse::<TOut>().unwrap();
let inp: Vec<TIn> = inp_str.split(' ')
.filter(|num| num.len() > 0)
.map(|num| num.trim().parse().unwrap())
.collect();
vectors.push(TestVector::<TIn, TOut> {
inp,
out
});
}
vectors
}
#[derive(Debug, Clone, PartialEq)]
pub struct DataArrOfReals {
pub vec: Vec<f64>,
pub valid: bool
}
impl FromStr for DataArrOfReals {
type Err = <f64 as FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
// TODO: maybe better handling, as an error?
// this would mean also reimplementing load_test_file to be able to supply
// out the error, but only for the output...
if !s.starts_with('[') {
return Ok(
DataArrOfReals {
valid: false,
vec: vec![]
}
)
}
let trimmed = &s[1..s.len()-1];
Ok(DataArrOfReals {
valid: true,
vec: trimmed.split(',')
.map(|x| x.trim().parse::<f64>())
.collect::<Result<Vec<f64>, _>>()?
})
}
}