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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
pub mod nav;
pub mod db;
use chrono::prelude::*;
use log::*;
use std::collections::HashMap;
use lazy_static::*;
use std::sync::RwLock;
use config::*;
lazy_static! {
static ref SETTINGS: RwLock<Config> = RwLock::new({
let mut settings = config::Config::default();
settings
.merge(config::File::with_name("Settings")).unwrap()
.merge(config::Environment::with_prefix("APP")).unwrap();
settings
});
}
pub fn app_config(key: &str) -> String {
let app_config = SETTINGS.read().unwrap().clone().try_into::<HashMap<String, String>>().unwrap();
app_config.get(key).unwrap().to_string()
}
pub fn process(inputs: &str) -> Vec<nav::Record> {
let (scheme_code_numbers, isin_codes) = extract(inputs);
let today = Local::today();
let conn = db::open_connection(&today.year());
let status = db::get_retrieval_status(&today, &conn);
if status == 0 {
debug!("Latest NAV NOT FOUND...");
nav::backup_latest_nav(&conn);
db::delete_latest_nav(&conn);
nav::retrieve_csv_data(&conn).unwrap();
db::update_retrieval_status(&today, &conn);
}
let net_asset_values: Vec<nav::Record> = nav::find_latest_for(scheme_code_numbers, isin_codes, &conn);
debug!("END: finding latest nav....with results: {:?}", net_asset_values);
net_asset_values
}
fn extract(codes: &str) -> (Vec<u32>, Vec<&str>) {
debug!("START: extract ....");
let split_codes: Vec<&str> = codes.split(|c| c == ',' || c == ' ' || c ==';' || c == '+' || c == '\r' || c == '\n').collect();
let mut trimmed_codes = vec![];
for code in split_codes {
trimmed_codes.push( code.trim() )
}
let mut scheme_codes = vec![];
let mut isin_codes = vec![];
for code in trimmed_codes {
match code.len() {
6 => { scheme_codes.push(code); },
12 => { isin_codes.push(code); },
_ => { debug!("invalid code {:?}", code); }
}
}
let mut scheme_code_numbers = vec![];
for code in &scheme_codes {
scheme_code_numbers.push( code.parse::<u32>().unwrap() );
}
debug!("END: extract ....returns ({:?}, {:?})", scheme_code_numbers, isin_codes);
(scheme_code_numbers, isin_codes)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_extract_scheme_number() {
let user_input_string = "119550";
let (actual_scheme_numbers, actual_isin_codes) = extract(user_input_string);
let expected_scheme_numbers: Vec<u32> = vec![119550];
let expected_isin_codes: Vec<&str> = [].to_vec();
assert_eq!(actual_scheme_numbers, expected_scheme_numbers);
assert_eq!(actual_isin_codes.len(), expected_isin_codes.len());
}
#[test]
fn test_extract_scheme_numbers() {
let user_input_string = "119550, 119551";
let (actual_scheme_numbers, actual_isin_codes) = extract(user_input_string);
let expected_scheme_numbers: Vec<u32> = vec![119550, 119551];
let expected_isin_codes: Vec<&str> = [].to_vec();
assert_eq!(actual_scheme_numbers, expected_scheme_numbers);
assert_eq!(actual_isin_codes.len(), expected_isin_codes.len());
}
#[test]
fn test_extract_isin_code() {
let user_input_string = "INF209K01YM2";
let (actual_scheme_numbers, actual_isin_codes) = extract(user_input_string);
let expected_scheme_numbers: Vec<u32> = [].to_vec();
let expected_isin_codes: Vec<&str> = vec!["INF209K01YM2"];
assert_eq!(actual_scheme_numbers.len(), expected_scheme_numbers.len());
assert_eq!(actual_isin_codes, expected_isin_codes);
}
#[test]
fn test_extract_isin_codes() {
let user_input_string = "INF209K01YM2, INF209K01YO8";
let (actual_scheme_numbers, actual_isin_codes) = extract(user_input_string);
let expected_scheme_numbers: Vec<u32> = [].to_vec();
let expected_isin_codes: Vec<&str> = vec!["INF209K01YM2", "INF209K01YO8"];
assert_eq!(actual_scheme_numbers.len(), expected_scheme_numbers.len());
assert_eq!(actual_isin_codes, expected_isin_codes);
}
#[test]
fn test_extract_isin_and_scheme() {
let user_input_string = "INF209K01YM2, 119550, INF209K01YO8, 119551";
let (actual_scheme_numbers, actual_isin_codes) = extract(user_input_string);
let expected_scheme_numbers: Vec<u32> = vec![119550, 119551];
let expected_isin_codes: Vec<&str> = vec!["INF209K01YM2", "INF209K01YO8"];
assert_eq!(actual_scheme_numbers, expected_scheme_numbers);
assert_eq!(actual_isin_codes, expected_isin_codes);
}
#[test]
fn test_extract_on_code_separators() {
let user_input_string = "INF209K01YM2, 119550 INF209K01YO8; 119551 + INF209K01LX6";
let (actual_scheme_numbers, actual_isin_codes) = extract(user_input_string);
let expected_scheme_numbers: Vec<u32> = vec![119550, 119551];
let expected_isin_codes: Vec<&str> = vec!["INF209K01YM2", "INF209K01YO8", "INF209K01LX6"];
assert_eq!(actual_scheme_numbers, expected_scheme_numbers);
assert_eq!(actual_isin_codes, expected_isin_codes);
}
}