use std::collections::HashMap;
use super::{
failures::ErrorCases,
traits::{CheckedCalc, CheckedType},
types::DataSet,
};
use crate::{
balancer::handler::balancer,
parser::handler::parser,
public::{cell::Cell, structs::ChemicalEquation},
};
pub struct Handler<'a, T> {
equ: &'a str,
ds: HashMap<&'static str, Vec<Vec<Cell<T>>>>,
cd: ChemicalEquation,
}
impl<'a, T: CheckedType + CheckedCalc> Handler<'a, T>
where
std::num::ParseIntError: std::convert::From<<T as num::Num>::FromStrRadixErr>
+ std::convert::From<<T as std::str::FromStr>::Err>,
{
pub fn new(equ: &'a str) -> Self {
Handler {
equ,
ds: HashMap::new(),
cd: ChemicalEquation::new(),
}
}
pub fn handle(&mut self) -> Result<DataSet<&T>, ErrorCases> {
self.parse()?;
self.balance()?;
Ok((&self.cd, fromcell(&self.ds["Balancer"])?))
}
pub fn parse(&mut self) -> Result<DataSet<&T>, ErrorCases> {
match parser::<Cell<T>>(self.equ)? {
(cd, data) => {
self.cd = cd;
self.ds.insert("Parser", data);
}
}
Ok((&self.cd, fromcell(&self.ds["Parser"])?))
}
fn balance(&mut self) -> Result<(), ErrorCases> {
self.ds.insert(
"Balancer",
balancer::<Cell<T>>((&self.cd, &self.ds["Parser"]))?,
);
Ok(())
}
}
fn check_tag<T>(v: &[Vec<Cell<T>>]) -> bool {
v.iter().all(|x| x.iter().all(|x| !x.get_tag()))
}
fn fromcell<T>(v: &[Vec<Cell<T>>]) -> Result<Vec<Vec<&T>>, ErrorCases> {
if !check_tag(v) {
return Err(ErrorCases::Overflow);
}
Ok(v.iter()
.map(|x| x.iter().map(|c| c.get_data()).collect::<Vec<_>>())
.collect::<Vec<_>>())
}