Skip to content

Instantly share code, notes, and snippets.

@LEXUGE
Created January 30, 2019 16:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LEXUGE/6d0e93d41f2e11d6abc44f55935d6204 to your computer and use it in GitHub Desktop.
Save LEXUGE/6d0e93d41f2e11d6abc44f55935d6204 to your computer and use it in GitHub Desktop.
// Copyright 2017-2019 LEXUGE
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
use std::collections::HashMap;
// inside use(s)
use super::{
failures::ErrorCases,
traits::{CheckedCalc, CheckedType},
types::DataSetOut,
};
use crate::public::structs::ChemicalEquation;
use crate::{balancer::handler::balancer, parser::handler::parser, public::cell::Cell};
/// A handler which store the equation and other information
pub struct Handler<'a,'b, T> {
equ: &'a str,
ds: HashMap<&'static str, Vec<Vec<Cell<T>>>>,
ds_raw: HashMap<&'static str, Vec<Vec<&'b T>>>,
cd: ChemicalEquation,
}
impl<'a,'b, T: CheckedType + CheckedCalc> Handler<'a,'b, T>
where
std::num::ParseIntError: std::convert::From<<T as num::Num>::FromStrRadixErr>
+ std::convert::From<<T as std::str::FromStr>::Err>,
{
/// Create a `Handler` by given equation
pub fn new(equ: &'a str) -> Self {
Handler {
equ,
ds: HashMap::new(),
ds_raw: HashMap::new(),
cd: ChemicalEquation::new(),
}
}
pub fn handle(&mut self) -> Result<DataSetOut<&'b T>, ErrorCases> {
self.parse()?;
self.balance()?;
Ok((&self.cd, &self.ds_raw.get("Balancer").unwrap()))
}
/// Parse the equation
pub fn parse(&mut self) -> Result<DataSetOut<&T>, ErrorCases> {
match parser::<Cell<T>>(self.equ)? {
(cd, data) => {
self.cd = cd;
self.ds.insert("Parser", data);
self.ds_raw
.insert("Parser", fromcell(self.ds.get("Parser").unwrap())?);
}
}
Ok((&self.cd, &self.ds_raw.get("Parser").unwrap()))
}
// AlphaForce Balancer
fn balance(&mut self) -> Result<(), ErrorCases> {
let v = balancer::<Cell<T>>((&self.cd, &self.ds.get("Parser").unwrap()))?;
self.ds.entry("Balancer").or_insert(v);
self.ds_raw.entry("Balancer").or_insert(fromcell(self.ds.get("Balancer").unwrap())?);
Ok(())
}
}
// All `false` => `true` (It didn't overflow)
fn check_tag<T>(v: &[Vec<Cell<T>>]) -> bool {
v.iter().all(|x| x.iter().all(|x| !x.get_tag()))
}
fn fromcell<T: Clone>(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<_>>())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment