1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use alloc::string::String;
use alloc::string::ToString;
use alloc::vec::Vec;
use alloc::borrow::ToOwned;
use chrono::NaiveDateTime;
use chrono::Utc;
use crate::config::SmartCalcConfig;
use crate::types::*;
use crate::tokinizer::Tokinizer;
use chrono::NaiveTime;
use regex::Regex;
pub fn get_atom(config: &SmartCalcConfig, data: &str, group_item: &[Regex]) -> Vec<(usize, usize, Option<TokenType>, String)> {
let mut atoms = Vec::new();
for re in group_item.iter() {
for capture in re.captures_iter(data) {
let atom_type = capture.name("ATOM").unwrap().as_str();
let data = capture.name("DATA").unwrap().as_str();
let token_type = match atom_type {
"TIME" => {
let seconds = data.parse::<u32>().unwrap();
let date = Utc::now().naive_local().date();
let time = NaiveTime::from_num_seconds_from_midnight(seconds, 0);
let date_time = NaiveDateTime::new(date, time);
TokenType::Time(date_time, config.get_time_offset())
},
"MONEY" => {
let splited_data: Vec<&str> = data.split(';').collect();
match config.get_currency(splited_data[1].to_string()) {
Some(currency_info) => TokenType::Money(splited_data[0].parse::<f64>().unwrap(), currency_info.clone()),
None => {
log::info!("Currency information not found, {}", splited_data[1]);
continue
}
}
},
"NUMBER" => {
let number = data.parse::<f64>().unwrap();
TokenType::Number(number, NumberType::Decimal)
},
"PERCENT" => {
let number = data.parse::<f64>().unwrap();
TokenType::Percent(number)
},
"OPERATOR" => TokenType::Operator(data.chars().next().unwrap()),
_ => {
log::info!("Atom type not found, {}", atom_type);
continue
}
};
atoms.push((capture.get(0).unwrap().start(), capture.get(0).unwrap().end(), Some(token_type), capture.get(0).unwrap().as_str().to_string()))
}
}
atoms
}
pub fn atom_regex_parser(config: &SmartCalcConfig, tokinizer: &mut Tokinizer, group_item: &[Regex]) {
let atoms = get_atom(config, &tokinizer.data.to_owned(), group_item);
for (start, end, token_type, text) in atoms {
tokinizer.add_token_location(start, end, token_type, text);
}
}
#[cfg(test)]
#[test]
fn operator_test() {
use core::ops::Deref;
use crate::tokinizer::regex_tokinizer;
use crate::tokinizer::test::setup_tokinizer;
use crate::config::SmartCalcConfig;
use crate::session::Session;
let mut session = Session::new();
let config = SmartCalcConfig::default();
let mut tokinizer_mut = setup_tokinizer("[OPERATOR:+] [PERCENT:-29.1] [TIME:44100] [NUMBER:-222.333] [MONEY:200;try]".to_string(), &mut session, &config);
regex_tokinizer(&mut tokinizer_mut);
let tokens = &tokinizer_mut.token_infos;
assert_eq!(tokens.len(), 5);
assert_eq!(tokens[0].start, 0);
assert_eq!(tokens[0].end, 12);
assert_eq!(tokens[0].token_type.borrow().deref(), &Some(TokenType::Operator('+')));
assert_eq!(tokens[1].start, 13);
assert_eq!(tokens[1].end, 28);
assert_eq!(tokens[1].token_type.borrow().deref(), &Some(TokenType::Percent(-29.1)));
assert_eq!(tokens[2].start, 29);
assert_eq!(tokens[2].end, 41);
assert_eq!(tokens[2].token_type.borrow().deref(), &Some(TokenType::Time(chrono::Utc::today().and_hms(12, 15, 0).naive_utc(), config.get_time_offset())));
assert_eq!(tokens[3].start, 43);
assert_eq!(tokens[3].end, 60);
assert_eq!(tokens[3].token_type.borrow().deref(), &Some(TokenType::Number(-222.333, NumberType::Decimal)));
assert_eq!(tokens[4].start, 61);
assert_eq!(tokens[4].end, 76);
assert_eq!(tokens[4].token_type.borrow().deref(), &Some(TokenType::Money(200.0, config.get_currency("try".to_string()).unwrap())));
}