Skip to content

Commit 0304a32

Browse files
committed
v0.2.1 OOP restructured, added integration-tests and fixed bugs
1 parent 45b2880 commit 0304a32

10 files changed

+184
-122
lines changed

Cargo.lock

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[package]
22
name = "lib_xch"
3-
version = "0.2.0"
3+
version = "0.2.1"
44
authors = ["LEXUGE <LEXUGEyky@outlook.com>"]
55
description = "Crate xch-ceb's official lib"
66
license = "GPL-3.0"
77
repository = "https://github.com/LEXUGE/lib-xch-ceb"
88

99
[dependencies]
10-
lazy_static = "1.0.0"
11-
regex = "0.2.5"
10+
lazy_static = "^1.x"
11+
regex = "^0.2"

README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
# lib-xch-ceb
2-
Crate xch-ceb's library
2+
This is crate [xch-ceb](https://crates.io/crates/xch-ceb)'s official lib.
3+
[lib_xch on crates.io](https://crates.io/crates/lib_xch)
4+
[lib_xch's documentation](https://docs.rs/lib_xch)
5+
6+
# Goal
7+
Fast, Small, Safe.

src/handler.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use balancer_mod::xch_try;
3030
pub fn handler_api(equation: String, searching_range: i32) -> Result<Vec<i32>, ErrorHandler> {
3131
// T is successful traversal vector, E is list vector which parser returned.
3232
let mut traversal: Vec<i32> = Vec::new();
33-
let (chemical_equation_struct, elements_table, list) = match xch_parser(equation) {
33+
let (chemical_equation_struct, elements_table_len, list) = match xch_parser(equation) {
3434
Ok(some) => some,
3535
Err(e) => {
3636
return Err(ErrorHandler {
@@ -48,7 +48,7 @@ pub fn handler_api(equation: String, searching_range: i32) -> Result<Vec<i32>, E
4848
&mut traversal,
4949
&list,
5050
&chemical_equation_struct,
51-
elements_table.len(),
51+
elements_table_len,
5252
) {
5353
Ok(true) => Ok(traversal),
5454
Ok(false) => Err(ErrorHandler {

src/lib.rs

-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,3 @@ pub mod handler;
2222
mod parser_mod;
2323
mod balancer_mod;
2424
mod structs;
25-
26-
#[cfg(test)]
27-
mod tests;

src/parser_mod/legal_check_util.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
// You should have received a copy of the GNU General Public License
1414
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1515

16+
// Overall: This is the source code of the Delta-3 Parser.
17+
1618
pub fn legal_check(equation: &String) -> Result<bool, String> {
1719
let equation = equation.chars().into_iter().collect::<Vec<_>>();
1820
let mut tmp = 0;
@@ -53,8 +55,7 @@ fn brackets_matcher(formula: &Vec<char>, pos: usize, mode: bool) -> Result<usize
5355
}
5456
if formula[i] == ')' {
5557
if fake_stack == 0 {
56-
let x: Result<usize, String> = Ok(i);
57-
return x;
58+
return Ok(i);
5859
} else {
5960
fake_stack = fake_stack - 1;
6061
}

src/parser_mod/mod.rs

+22-85
Original file line numberDiff line numberDiff line change
@@ -17,64 +17,53 @@
1717

1818
// mods
1919
mod legal_check_util;
20+
mod parser_struct;
2021

2122
use regex::Regex;
2223
use std::string::String;
2324
use std::vec::Vec;
2425
use std::i32;
2526
// inside uses
26-
use structs::{ChemicalEquation, ElementStruct};
27+
use structs::ChemicalEquation;
28+
use self::parser_struct::{TableDesc,FormulaDesc,TokenDesc};
2729
use self::legal_check_util::{legal_check, legal_check_brackets};
2830

29-
struct FormulaDesc {
30-
formula_self: String,
31-
times: i32,
32-
all: String,
33-
}
34-
35-
struct TokenDesc {
36-
token_name: String,
37-
times: i32,
38-
}
39-
40-
pub fn xch_parser(equation: String) -> Result<(ChemicalEquation, Vec<ElementStruct>, Vec<Vec<i32>>),String> {
31+
pub fn xch_parser(equation: String) -> Result<(ChemicalEquation, usize, Vec<Vec<i32>>),String> {
4132
legal_check(&equation)?;
4233
let mut chemical_equation_struct = ChemicalEquation {
4334
left_num: 0,
4435
right_num: 0,
4536
sum: 0,
4637
};
47-
let mut elements_table: Vec<ElementStruct> = Vec::new(); // store the index of elements
48-
let mut list: Vec<Vec<i32>> = Vec::new();
49-
// Unicode slice safe
50-
51-
// block to call parsers
52-
{
38+
{ // block to get chemical_equation_struct.sum
5339
let v: Vec<&str> = equation.split('=').collect();
5440
let equation_left: String = String::from(v[0]);
5541
let equation_right: String = String::from(v[1]);
56-
5742
chemical_equation_struct.sum =
5843
parser_get_sum(&equation_left)? + parser_get_sum(&equation_right)?;
59-
list.push(generate_n_vec(chemical_equation_struct.sum + 1)); // first access will be like list[1][1]
44+
}
45+
let mut table = TableDesc::new(chemical_equation_struct.sum);
46+
table.update_list_vec(); // first access will be like list[1][1]
47+
48+
{ // block to call parsers
49+
let v: Vec<&str> = equation.split('=').collect();
50+
let equation_left: String = String::from(v[0]);
51+
let equation_right: String = String::from(v[1]);
52+
6053
chemical_equation_struct.left_num = part_parser(
6154
&equation_left,
62-
&mut elements_table,
63-
&mut list,
55+
&mut table,
6456
0,
65-
chemical_equation_struct.sum,
6657
)?;
6758
chemical_equation_struct.right_num = part_parser(
6859
&equation_right,
69-
&mut elements_table,
70-
&mut list,
60+
&mut table,
7161
chemical_equation_struct.left_num,
72-
chemical_equation_struct.sum,
7362
)?;
7463
}
7564

7665
// return
77-
Ok((chemical_equation_struct, elements_table, list))
66+
Ok((chemical_equation_struct, table.get_elements_table_len(), table.get_list()))
7867
}
7968

8069
fn parser_get_sum(equation: &String) -> Result<i32,String> {
@@ -90,34 +79,22 @@ fn parser_get_sum(equation: &String) -> Result<i32,String> {
9079

9180
fn part_parser(
9281
equation: &String,
93-
elements_table: &mut Vec<ElementStruct>,
94-
list: &mut Vec<Vec<i32>>,
82+
table: &mut TableDesc,
9583
begin: i32,
96-
equation_sum: i32,
9784
) -> Result<i32,String> {
9885
let mut sum = begin;
9986
for formula in equation.split('+') {
10087
sum = sum + 1;
10188
legal_check_brackets(&formula.to_string())?;
10289
parser_formula(
10390
&formula.to_string(),
104-
elements_table,
91+
table,
10592
sum as usize,
106-
list,
107-
equation_sum,
10893
)?;
10994
}
11095
Ok(sum - begin)
11196
}
11297

113-
fn generate_n_vec(n: i32) -> Vec<i32> {
114-
let mut v: Vec<i32> = Vec::new();
115-
for _ in 0..n {
116-
v.push(0);
117-
}
118-
v
119-
}
120-
12198
fn formula_spliter(target: &str) -> Result<Vec<FormulaDesc>, String> {
12299
let mut v: Vec<FormulaDesc> = Vec::new();
123100
lazy_static! {
@@ -194,60 +171,20 @@ fn replace_phrase(target: &str, src: &str, des: &str) -> String {
194171
str::replace(target, src, des)
195172
}
196173

197-
fn store_in_table(
198-
formula: &String,
199-
elements_table: &mut Vec<ElementStruct>,
200-
location: usize,
201-
list: &mut Vec<Vec<i32>>,
202-
formula_sum: i32,
203-
) -> Result<bool, String> {
204-
for t in get_token(formula)? {
205-
if find_element_in_table(&t.token_name, elements_table).is_ok() == false {
206-
let len = elements_table.len();
207-
elements_table.push(ElementStruct {
208-
name: t.token_name.clone(),
209-
num: len + 1, // WARN: the elements_table[0].num will be 1
210-
});
211-
list.push(generate_n_vec(formula_sum + 1));
212-
}
213-
214-
{
215-
// store data in table
216-
let tmp = find_element_in_table(&t.token_name, elements_table).unwrap();
217-
list[tmp][location] = match list[tmp][location].checked_add(t.times) {
218-
Some(s) => s,
219-
None => return Err("[ERROR] i32 overflow".to_string()),
220-
}
221-
}
222-
}
223-
Ok(true)
224-
}
225-
226174
fn parser_formula(
227175
// parse the chemical formula
228176
formula: &String,
229-
elements_table: &mut Vec<ElementStruct>,
177+
table: &mut TableDesc,
230178
location: usize,
231-
list: &mut Vec<Vec<i32>>,
232-
formula_sum: i32,
233179
) -> Result<bool, String>{
234180
let formula_backup = formula;
235181
let mut formula = format!("({})", formula_backup);
236182

237183
while formula_spliter(&formula).is_ok() == true {
238-
for p in formula_spliter(&formula).unwrap() {
184+
for p in formula_spliter(&formula)? {
239185
formula = replace_phrase(&formula, &p.all, &(mul_phrase(&p)?));
240186
}
241187
}
242-
store_in_table(&formula, elements_table, location, list, formula_sum)?;
188+
table.store_in_table(&formula,location)?;
243189
Ok(true)
244190
}
245-
246-
fn find_element_in_table(target: &String, e_t: &mut Vec<ElementStruct>) -> Result<usize, String> {
247-
for i in e_t {
248-
if i.name == *target {
249-
return Ok(i.num);
250-
}
251-
}
252-
Err("[ERROR] Not found!".to_string())
253-
}

src/parser_mod/parser_struct.rs

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright 2017-2018 LEXUGE
2+
//
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// This program is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU General Public License
14+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
16+
// Overall: This is the source code of the Delta-3 Parser.
17+
18+
// inside uses
19+
use structs::ElementStruct;
20+
use parser_mod::get_token;
21+
22+
pub struct FormulaDesc {
23+
pub formula_self: String,
24+
pub times: i32,
25+
pub all: String,
26+
}
27+
28+
pub struct TokenDesc {
29+
pub token_name: String,
30+
pub times: i32,
31+
}
32+
33+
// Object-Oriented
34+
pub struct TableDesc {
35+
elements_table: Vec<ElementStruct>, // store the index of elements
36+
list: Vec<Vec<i32>>,
37+
formula_sum: i32,
38+
}
39+
40+
impl TableDesc {
41+
pub fn store_in_table(&mut self, formula: &String, location: usize) -> Result<bool, String> {
42+
for t in get_token(formula)? {
43+
if self.find_element_in_table(&t.token_name).is_ok() == false {
44+
let len = self.elements_table.len();
45+
self.elements_table.push(ElementStruct {
46+
name: t.token_name.clone(),
47+
num: len + 1, // WARN: the elements_table[0].num will be 1
48+
});
49+
self.update_list_vec();
50+
}
51+
52+
{
53+
// store data in table
54+
let tmp = self.find_element_in_table(&t.token_name)?; // It have been checked.
55+
self.list[tmp][location] = match self.list[tmp][location].checked_add(t.times) {
56+
Some(s) => s,
57+
None => return Err("[ERROR] i32 overflow".to_string()),
58+
}
59+
}
60+
}
61+
Ok(true)
62+
}
63+
64+
pub fn get_elements_table_len(&self) -> usize {
65+
self.elements_table.len()
66+
}
67+
68+
pub fn get_list(&self) -> Vec<Vec<i32>> {
69+
(self.list).to_vec()
70+
}
71+
72+
pub fn new(sum: i32) -> Self { // PLEASE call update_list_vec after new!
73+
Self {
74+
elements_table: Vec::new(),
75+
list: Vec::new(),
76+
formula_sum: sum,
77+
}
78+
}
79+
80+
pub fn update_list_vec(&mut self) {
81+
let v = self.generate_vec();
82+
self.list.push(v);
83+
}
84+
85+
fn generate_vec(&self) -> Vec<i32> {
86+
let mut v: Vec<i32> = Vec::new();
87+
for _ in 0..self.formula_sum + 1 {
88+
v.push(0);
89+
}
90+
v
91+
}
92+
93+
fn find_element_in_table(&self, target: &String) -> Result<usize, String> {
94+
for i in &(self.elements_table) {
95+
if i.name == *target {
96+
return Ok(i.num);
97+
}
98+
}
99+
Err("[ERROR] Not found!".to_string())
100+
}
101+
}

0 commit comments

Comments
 (0)