use crate::macros::codegen_case_create_impl;
use std::fmt::Debug;
pub struct Case<T, G, P> {
pub inputs: Vec<T>,
pub params: Vec<P>,
pub values: Vec<G>,
index: i32,
}
impl<T, G, P> Case<T, G, P>
where
T: PartialEq + Debug,
G: PartialEq + Debug,
P: PartialEq + Debug,
{
pub fn new(input: T, values: Vec<G>) -> Case<T, G, P> {
Case {
inputs: vec![input],
params: vec![],
values: values,
index: 0,
}
}
pub fn new_multi(inputs: Vec<T>, values: Vec<G>) -> Case<T, G, P> {
Case {
inputs: inputs,
params: vec![],
values: values,
index: 0,
}
}
pub fn new_params(input: T, params: Vec<P>, values: Vec<G>) -> Case<T, G, P> {
Case {
inputs: vec![input],
params: params,
values: values,
index: 0,
}
}
pub fn new_params_multi(inputs: Vec<T>, params: Vec<P>, values: Vec<G>) -> Case<T, G, P> {
Case {
inputs: inputs,
params: params,
values: values,
index: 0,
}
}
pub fn is_valid(&self, result: G) {
if self.values.len() == 0 {
assert!(false);
}
for val in self.values.iter() {
if *val == result {
return assert!(true);
}
}
if self.values.len() == 1 {
if self.inputs.len() == 1 {
assert!(
false,
"[#{}] INPUT=`{:?}`, OUTPUT=`{:?}`, EXPECTATION=`{:?}`",
self.index, &self.inputs[0], &result, self.values[0]
);
} else {
assert!(
false,
"[#{}] INPUT=`[{:?}]`, OUTPUT=`{:?}`, EXPECTATION=`{:?}`",
self.index, self.inputs, &result, self.values[0]
);
}
} else {
assert!(
false,
"Result `{:?}` doesn't match any expectations",
&result
);
}
}
pub fn label(&self) -> String {
self.index.to_string()
}
pub fn input(&self) -> &T {
&self.inputs[0]
}
}
pub struct CaseGroup<T, G, P> {
cases: Vec<Case<T, G, P>>,
count: i32,
}
impl<T, G, P> CaseGroup<T, G, P> {
pub fn new() -> CaseGroup<T, G, P> {
CaseGroup {
cases: vec![],
count: 0,
}
}
pub fn add(&mut self, mut case: Case<T, G, P>) {
self.count += 1;
case.index = self.count;
self.cases.push(case);
}
pub fn all(self) -> Vec<Case<T, G, P>> {
self.cases
}
}
impl<G, P> CaseGroup<String, G, P>
where
P: PartialEq + Debug,
G: PartialEq + Debug,
{
pub fn create(&mut self, ipt: &str, exp: Vec<G>) {
self.add(Case::new(ipt.to_string(), exp));
}
pub fn create_param(&mut self, ipt: &str, exp: Vec<G>, params: Vec<P>) {
self.add(Case::new_params(ipt.to_string(), params, exp));
}
pub fn create_multi(&mut self, ipts: Vec<&str>, exp: Vec<G>) {
self.add(Case::new_multi(
ipts.iter().map(|x| x.to_string()).collect(),
exp,
));
}
pub fn create_param_multi(&mut self, ipts: Vec<&str>, exp: Vec<G>, params: Vec<P>) {
self.add(Case::new_params_multi(
ipts.iter().map(|x| x.to_string()).collect(),
params,
exp,
));
}
}
codegen_case_create_impl!(i32, i32, i32);
codegen_case_create_impl!(i32, String, i32);
codegen_case_create_impl!(i32, bool, i32);
codegen_case_create_impl!(Vec<i32>, i32, i32);
codegen_case_create_impl!(Vec<i32>, Vec<Vec<i32>>, i32);