smartcalc_tauri/tokinizer/
tools.rs

1/*
2 * smartcalc v1.0.8
3 * Copyright (c) Erhan BARIS (Ruslan Ognyanov Asenov)
4 * Licensed under the GNU General Public License v2.0.
5 */
6
7use alloc::rc::Rc;
8use alloc::string::String;
9use alloc::string::ToString;
10use alloc::collections::btree_map::BTreeMap;
11use chrono::NaiveDateTime;
12use chrono::Utc;
13use crate::compiler::date::DateItem;
14use crate::compiler::date_time::DateTimeItem;
15use crate::compiler::duration::DurationItem;
16use crate::compiler::number::NumberItem;
17use crate::compiler::percent::PercentItem;
18use crate::compiler::dynamic_type::DynamicTypeItem;
19use crate::compiler::DataItem;
20use crate::compiler::time::TimeItem;
21use crate::types::TimeOffset;
22use core::ops::Deref;
23use chrono::{Duration, NaiveDate};
24
25use crate::config::SmartCalcConfig;
26use crate::config::DynamicType;
27use crate::types::CurrencyInfo;
28use crate::types::Money;
29use crate::types::{TokenType, SmartCalcAstType};
30use crate::tokinizer::TokenInfo;
31use crate::compiler::money::MoneyItem;
32
33pub fn read_currency(config: &SmartCalcConfig, currency: &'_ str) -> Option<Rc<CurrencyInfo>> {
34    match config.currency_alias.get(&currency.to_lowercase()) {
35        Some(symbol) => Some(symbol.clone()),
36        _ => config.currency.get(&currency.to_lowercase()).cloned()
37    }
38}
39
40pub fn get_number(field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<f64> {
41    return match fields.get(field_name) {
42        Some(data) => match data.token_type.borrow().deref() {
43            Some(token) => match &token {
44                TokenType::Number(number, _) => Some(*number),
45                TokenType::Variable(variable) => {
46                    match variable.data.borrow().deref().deref() {
47                        SmartCalcAstType::Item(item) => item.as_any().downcast_ref::<NumberItem>().map(|number| number.get_underlying_number()),
48                        _ => None
49                    }
50                },
51                _ => None
52            },
53            _ => None
54        },
55        _ => None
56    }
57}
58
59pub fn get_duration(field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<Duration> {
60    return match fields.get(field_name) {
61        Some(data) => match &data.token_type.borrow().deref() {
62            Some(token) => match &token {
63                TokenType::Duration(duration) => Some(*duration),
64                TokenType::Variable(variable) => {
65                    match variable.data.borrow().deref().deref() {
66                        SmartCalcAstType::Item(item) => item.as_any().downcast_ref::<DurationItem>().map(|number| number.get_duration()),
67                        _ => None
68                    }
69                },
70                _ => None
71            },
72            _ => None
73        },
74        _ => None
75    }
76}
77
78pub fn get_time(field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<(NaiveDateTime, TimeOffset)> {
79    return match fields.get(field_name) {
80        Some(data) => match &data.token_type.borrow().deref() {
81            Some(token) => match &token {
82                TokenType::Time(time, tz) => Some((*time, tz.clone())),
83                TokenType::Variable(variable) => {
84                    match variable.data.borrow().deref().deref() {
85                        SmartCalcAstType::Item(item) => item.as_any().downcast_ref::<TimeItem>().map(|time_item| (time_item.get_time(), time_item.get_tz())),
86                        _ => None
87                    }
88                },
89                _ => None
90            },
91            _ => None
92        },
93        _ => None
94    }
95}
96
97pub fn get_date(field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<(NaiveDate, TimeOffset)> {
98    return match fields.get(field_name) {
99        Some(data) => match &data.token_type.borrow().deref() {
100            Some(token) => match &token {
101                TokenType::Date(date, tz) => Some((*date, tz.clone())),
102                TokenType::Variable(variable) => {
103                    match variable.data.borrow().deref().deref() {
104                        SmartCalcAstType::Item(item) => item.as_any().downcast_ref::<DateItem>().map(|date_item| (date_item.get_date(), date_item.get_tz())),
105                        _ => None
106                    }
107                },
108                _ => None
109            },
110            _ => None
111        },
112        _ => None
113    }
114}
115
116
117pub fn get_date_time(field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<(NaiveDateTime, TimeOffset)> {
118    return match fields.get(field_name) {
119        Some(data) => match &data.token_type.borrow().deref() {
120            Some(token) => match &token {
121                TokenType::DateTime(date, tz) => Some((*date, tz.clone())),
122                TokenType::Variable(variable) => {
123                    match variable.data.borrow().deref().deref() {
124                        SmartCalcAstType::Item(item) => item.as_any().downcast_ref::<DateTimeItem>().map(|date_item| (date_item.get_date_time(), date_item.get_tz())),
125                        _ => None
126                    }
127                },
128                _ => None
129            },
130            _ => None
131        },
132        _ => None
133    }
134}
135
136pub fn get_text(field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<String> {
137    return match fields.get(field_name) {
138        Some(data) => match &data.token_type.borrow().deref() {
139            Some(TokenType::Text(text)) =>  Some(text.to_string()),
140            _ => None
141        },
142        _ => None
143    }
144}
145
146pub fn get_dynamic_type(field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<(f64, Rc<DynamicType>)> {
147    return match &fields.get(field_name) {
148        Some(data) =>match &data.token_type.borrow().deref() {
149            Some(token) => match &token {
150                TokenType::DynamicType(number, dynamic_type) => Some((*number, dynamic_type.clone())),
151                TokenType::Variable(variable) => {
152                    match variable.data.borrow().deref().deref() {
153                        SmartCalcAstType::Item(item) => item.as_any().downcast_ref::<DynamicTypeItem>().map(|dynamic_type| (dynamic_type.get_number(), dynamic_type.get_type())),
154                        _ => None
155                    }
156                },
157                _ => None
158            },
159            _ => None
160        },
161        _ => None
162    }
163}
164
165pub fn get_timezone(field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<(String, i32)> {
166    return match fields.get(field_name) {
167        Some(data) => match &data.token_type.borrow().deref() {
168            Some(TokenType::Timezone(timezone, offset)) =>  Some((timezone.to_string(), *offset)),
169            _ => None
170        },
171        _ => None
172    }
173}
174
175pub fn get_month(field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<u32> {
176    return match &fields.get(field_name) {
177        Some(data) =>match &data.token_type.borrow().deref() {
178            Some(token) => match &token {
179                TokenType::Month(number) => Some(*number),
180                TokenType::Variable(variable) => {
181                    match variable.data.borrow().deref().deref() {
182                        SmartCalcAstType::Month(number) => Some(*number),
183                        _ => None
184                    }
185                },
186                _ => None
187            },
188            _ => None
189        },
190        _ => None
191    }
192}
193
194pub fn get_number_or_time(config: &SmartCalcConfig, field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<(NaiveDateTime, TimeOffset)> {
195    match get_number(field_name, fields) {
196        Some(number) => {
197            let date = Utc::now().naive_local().date();
198            let time = chrono::NaiveTime::from_hms(number as u32, 0, 0);
199            Some((NaiveDateTime::new(date, time), config.get_time_offset()))
200        },
201        None => get_time(field_name, fields)
202    }
203}
204
205pub fn get_number_or_price(config: &SmartCalcConfig, field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<f64> {
206    match get_number(field_name, fields) {
207        Some(number) => Some(number),
208        None => get_money(config, field_name, fields).map(|money| money.get_price())
209    }
210}
211
212pub fn get_number_or_month(field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<u32> {
213    match get_number(field_name, fields) {
214        Some(number) => Some(number as u32),
215        None => get_month(field_name, fields)
216    }
217}
218
219
220pub fn get_money(_: &SmartCalcConfig, field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<Money> {
221    return match &fields.get(field_name) {
222        Some(data) => match &data.token_type.borrow().deref() {
223            Some(token) => match &token {
224                TokenType::Money(price, currency) => Some(Money(*price, currency.clone())),
225                TokenType::Variable(variable) => {
226                    match variable.data.borrow().deref().deref() {
227                        SmartCalcAstType::Item(item) => item.as_any().downcast_ref::<MoneyItem>().map(|money_item| Money(money_item.get_price(), money_item.get_currency())),
228                        _ => None
229                    }
230                },
231                _ => None
232            },
233            _ => None
234        },
235        _ => None
236    }
237}
238
239pub fn get_currency(config: &SmartCalcConfig, field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<Rc<CurrencyInfo>> {
240    match &fields.get(field_name) {
241        Some(data) => match &data.token_type.borrow().deref() {
242            Some(token) => match &token {
243                TokenType::Text(currency) => read_currency(config, currency),
244                TokenType::Money(_, currency) => Some(currency.clone()),
245                TokenType::Variable(variable) => {
246                    match variable.data.borrow().deref().deref() {
247                        SmartCalcAstType::Item(item) => item.as_any().downcast_ref::<MoneyItem>().map(|money_item| money_item.get_currency()),
248                        _ => None
249                    }
250                },
251                _ => None
252            },
253            _ => None
254        },
255        _ => None
256    }
257}
258
259pub fn get_percent(field_name: &str, fields: &BTreeMap<String, Rc<TokenInfo>>) -> Option<f64> {
260    match &fields.get(field_name) {
261        Some(data) => match &data.token_type.borrow().deref() {
262            Some(token) => match &token {
263                TokenType::Percent(percent) => Some(*percent),
264                TokenType::Variable(variable) => {
265                    match variable.data.borrow().deref().deref() {
266                        SmartCalcAstType::Item(item) => item.as_any().downcast_ref::<PercentItem>().map(|percent_item| percent_item.get_underlying_number()),
267                        _ => None
268                    }
269                },
270                _ => None
271            },
272            _ => None
273        },
274        _ => None
275    }
276}