libsubconverter/settings/
ini_bindings.rs1use crate::models::cron::{CronTaskConfig, CronTaskConfigs};
2use crate::models::proxy_group_config::{ProxyGroupConfig, ProxyGroupConfigs, ProxyGroupType};
3use crate::models::regex_match_config::{RegexMatchConfig, RegexMatchConfigs};
4use crate::models::ruleset::{RulesetConfig, RulesetConfigs};
5use crate::utils::string::starts_with;
6
7fn parse_group_times(src: &str, interval: &mut u32, timeout: &mut u32, tolerance: &mut u32) {
10 let parts: Vec<&str> = src.split(',').collect();
11 if parts.len() >= 1 {
12 if let Ok(val) = parts[0].parse::<u32>() {
13 *interval = val;
14 }
15 }
16 if parts.len() >= 2 {
17 if let Ok(val) = parts[1].parse::<u32>() {
18 *timeout = val;
19 }
20 }
21 if parts.len() >= 3 {
22 if let Ok(val) = parts[2].parse::<u32>() {
23 *tolerance = val;
24 }
25 }
26}
27
28pub trait FromIni<T> {
30 fn from_ini(arr: &[String]) -> T;
32}
33
34pub trait FromIniWithDelimiter<T> {
36 fn from_ini_with_delimiter(arr: &[String], delimiter: &str) -> T;
38}
39
40impl FromIni<ProxyGroupConfigs> for ProxyGroupConfigs {
42 fn from_ini(arr: &[String]) -> ProxyGroupConfigs {
43 let mut confs = Vec::new();
44
45 for x in arr {
46 let mut rules_upper_bound;
47 let mut conf = ProxyGroupConfig::default();
48
49 let v_array: Vec<&str> = x.split('`').collect();
50 if v_array.len() < 3 {
51 continue;
52 }
53
54 conf.name = v_array[0].to_string();
55 let type_str = v_array[1];
56
57 rules_upper_bound = v_array.len();
58 conf.group_type = match type_str {
59 "select" => ProxyGroupType::Select,
60 "relay" => ProxyGroupType::Relay,
61 "url-test" => ProxyGroupType::URLTest,
62 "fallback" => ProxyGroupType::Fallback,
63 "load-balance" => ProxyGroupType::LoadBalance,
64 "ssid" => ProxyGroupType::SSID,
65 "smart" => ProxyGroupType::Smart,
66 _ => ProxyGroupType::Select,
67 };
68
69 if conf.group_type == ProxyGroupType::URLTest
70 || conf.group_type == ProxyGroupType::LoadBalance
71 || conf.group_type == ProxyGroupType::Fallback
72 {
73 if rules_upper_bound < 5 {
74 continue;
75 }
76 rules_upper_bound -= 2;
77 conf.url = v_array[rules_upper_bound].to_string();
78
79 let mut interval = 0;
80 let mut timeout = 5;
81 let mut tolerance = 0;
82 parse_group_times(
83 v_array[rules_upper_bound + 1],
84 &mut interval,
85 &mut timeout,
86 &mut tolerance,
87 );
88 conf.interval = interval;
89 conf.timeout = timeout;
90 conf.tolerance = tolerance;
91 }
92
93 for i in 2..rules_upper_bound {
94 if starts_with(v_array[i], "!!PROVIDER=") {
95 let provider_list: Vec<&str> = v_array[i][11..].split(',').collect();
96 for provider in provider_list {
97 conf.using_provider.push(provider.to_string());
98 }
99 } else {
100 conf.proxies.push(v_array[i].to_string());
101 }
102 }
103
104 confs.push(conf);
105 }
106
107 confs
108 }
109}
110
111impl FromIni<Vec<RulesetConfig>> for RulesetConfigs {
113 fn from_ini(arr: &[String]) -> Vec<RulesetConfig> {
114 let mut confs = Vec::new();
115
116 for x in arr {
117 let mut conf = RulesetConfig::default();
118
119 let pos = x.find(',');
120 if pos.is_none() {
121 continue;
122 }
123
124 let pos = pos.unwrap();
125 conf.group = x[..pos].to_string();
126
127 if x.len() > pos + 3 && &x[pos + 1..pos + 3] == "[]" {
129 conf.url = x[pos + 1..].to_string();
130 confs.push(conf);
131 continue;
132 }
133
134 let epos = x.rfind(',');
136 if pos != epos.unwrap_or(pos) {
137 let epos = epos.unwrap();
138 if let Ok(interval) = x[epos + 1..].parse::<u32>() {
139 conf.interval = interval;
140 }
141 conf.url = x[pos + 1..epos].to_string();
142 } else {
143 conf.url = x[pos + 1..].to_string();
144 }
145
146 confs.push(conf);
147 }
148
149 confs
150 }
151}
152
153impl FromIniWithDelimiter<RegexMatchConfigs> for RegexMatchConfigs {
156 fn from_ini_with_delimiter(arr: &[String], delimiter: &str) -> RegexMatchConfigs {
157 let mut confs = Vec::new();
158
159 for x in arr {
160 let mut conf = RegexMatchConfig::new(String::new(), String::new(), String::new());
161
162 if starts_with(x, "script:") {
164 conf.script = x[7..].to_string();
165 confs.push(conf);
166 continue;
167 }
168
169 let pos = x.rfind(delimiter);
171 conf._match = x[..pos.unwrap_or(x.len())].to_string();
172
173 if let Some(p) = pos {
174 if p < x.len() - 1 {
175 conf.replace = x[p + delimiter.len()..].to_string();
176 }
177 }
178
179 conf.compile();
180
181 confs.push(conf);
182 }
183
184 confs
185 }
186}
187
188impl FromIni<CronTaskConfigs> for CronTaskConfigs {
190 fn from_ini(arr: &[String]) -> CronTaskConfigs {
191 let mut confs = Vec::new();
192
193 for x in arr {
194 let mut conf = CronTaskConfig::default();
195
196 let v_array: Vec<&str> = x.split('`').collect();
197 if v_array.len() < 3 {
198 continue;
199 }
200
201 conf.name = v_array[0].to_string();
202 conf.cron_exp = v_array[1].to_string();
203 conf.path = v_array[2].to_string();
204
205 if v_array.len() > 3 {
206 if let Ok(timeout) = v_array[3].parse::<u32>() {
207 conf.timeout = timeout;
208 }
209 }
210
211 confs.push(conf);
212 }
213
214 confs
215 }
216}