feat: refactor

This commit is contained in:
GyDi
2022-08-12 03:20:55 +08:00
parent 178fd8e828
commit 7f6dac4271
22 changed files with 320 additions and 778 deletions

View File

@@ -63,19 +63,28 @@ pub fn use_valid_fields(mut valid: Vec<String>) -> Vec<String> {
.collect()
}
pub fn use_filter(config: Mapping, filter: Vec<String>) -> Mapping {
pub fn use_filter(config: Mapping, filter: &Vec<String>) -> Mapping {
let mut ret = Mapping::new();
for (key, value) in config.into_iter() {
key.as_str().map(|key_str| {
// change to lowercase
if let Some(key) = key.as_str() {
if filter.contains(&key.to_string()) {
ret.insert(Value::from(key), value);
}
}
}
ret
}
pub fn use_lowercase(config: Mapping) -> Mapping {
let mut ret = Mapping::new();
for (key, value) in config.into_iter() {
if let Some(key_str) = key.as_str() {
let mut key_str = String::from(key_str);
key_str.make_ascii_lowercase();
if filter.contains(&key_str) {
ret.insert(Value::from(key_str), value);
}
});
ret.insert(Value::from(key_str), value);
}
}
ret
}
@@ -95,3 +104,15 @@ pub fn use_sort(config: Mapping) -> Mapping {
});
ret
}
pub fn use_keys(config: &Mapping) -> Vec<String> {
config
.iter()
.filter_map(|(key, _)| key.as_str())
.map(|s| {
let mut s = s.to_string();
s.make_ascii_lowercase();
return s;
})
.collect()
}

View File

@@ -1,4 +1,4 @@
use super::{use_filter, use_valid_fields};
use super::{use_filter, use_lowercase};
use serde_yaml::{self, Mapping, Sequence, Value};
#[allow(unused)]
@@ -11,17 +11,16 @@ const MERGE_FIELDS: [&str; 6] = [
"append-proxy-groups",
];
pub fn use_merge(merge: Mapping, mut config: Mapping, valid: Vec<String>) -> Mapping {
let valid_list = use_valid_fields(valid);
let merge_valid = use_filter(merge.clone(), valid_list);
pub fn use_merge(merge: Mapping, mut config: Mapping) -> Mapping {
// 直接覆盖原字段
merge_valid.into_iter().for_each(|(key, value)| {
config.insert(key, value);
});
use_lowercase(merge.clone())
.into_iter()
.for_each(|(key, value)| {
config.insert(key, value);
});
let merge_list = MERGE_FIELDS.iter().map(|s| s.to_string());
let merge = use_filter(merge, merge_list.collect());
let merge = use_filter(merge, &merge_list.collect());
["rules", "proxies", "proxy-groups"]
.iter()
@@ -52,7 +51,6 @@ pub fn use_merge(merge: Mapping, mut config: Mapping, valid: Vec<String>) -> Map
config.insert(key_val, Value::from(list));
});
config
}
@@ -87,11 +85,7 @@ fn test_merge() -> anyhow::Result<()> {
let merge = serde_yaml::from_str::<Mapping>(merge)?;
let config = serde_yaml::from_str::<Mapping>(config)?;
let result = serde_yaml::to_string(&use_merge(
merge,
config,
vec!["tun"].iter().map(|s| s.to_string()).collect(),
))?;
let result = serde_yaml::to_string(&use_merge(merge, config))?;
println!("{result}");

View File

@@ -7,53 +7,63 @@ pub(self) use self::field::*;
use self::merge::*;
use self::script::*;
use self::tun::*;
use crate::core::PrfData;
use crate::core::ChainItem;
use crate::core::ChainType;
use serde_yaml::Mapping;
use std::collections::HashMap;
use std::collections::HashSet;
type ResultLog = Vec<(String, String)>;
pub fn runtime_config(
pub fn enhance_config(
clash_config: Mapping,
profile_config: Mapping,
profile_enhanced: Vec<PrfData>,
chain: Vec<ChainItem>,
valid: Vec<String>,
tun_mode: bool,
) -> (Mapping, HashMap<String, ResultLog>) {
) -> (Mapping, Vec<String>, HashMap<String, ResultLog>) {
let mut config = profile_config;
let mut result_map = HashMap::new();
let mut exists_keys = use_keys(&config);
profile_enhanced.into_iter().for_each(|data| {
if data.merge.is_some() {
config = use_merge(data.merge.unwrap(), config.to_owned(), valid.clone());
} else if data.script.is_some() {
let valid = use_valid_fields(valid);
chain.into_iter().for_each(|item| match item.data {
ChainType::Merge(merge) => {
exists_keys.extend(use_keys(&merge));
config = use_merge(merge, config.to_owned());
config = use_filter(config.to_owned(), &valid);
}
ChainType::Script(script) => {
let mut logs = vec![];
match use_script(data.script.unwrap(), config.to_owned(), valid.clone()) {
match use_script(script, config.to_owned()) {
Ok((res_config, res_logs)) => {
config = res_config;
exists_keys.extend(use_keys(&res_config));
config = use_filter(res_config, &valid);
logs.extend(res_logs);
}
Err(err) => {
logs.push(("error".into(), err.to_string()));
}
Err(err) => logs.push(("exception".into(), err.to_string())),
}
if let Some(uid) = data.item.uid {
result_map.insert(uid, logs);
}
result_map.insert(item.uid, logs);
}
});
config = use_filter(config, use_valid_fields(valid));
config = use_filter(config, &valid);
for (key, value) in clash_config.into_iter() {
config.insert(key, value);
}
config = use_filter(config, use_clash_fields());
let clash_fields = use_clash_fields();
config = use_filter(config, &clash_fields);
config = use_tun(config, tun_mode);
config = use_sort(config);
(config, result_map)
let mut exists_set = HashSet::new();
exists_set.extend(exists_keys.into_iter().filter(|s| clash_fields.contains(s)));
exists_keys = exists_set.into_iter().collect();
(config, exists_keys, result_map)
}

View File

@@ -1,12 +1,8 @@
use super::{use_filter, use_valid_fields};
use super::use_lowercase;
use anyhow::Result;
use serde_yaml::{self, Mapping};
use serde_yaml::Mapping;
pub fn use_script(
script: String,
config: Mapping,
valid: Vec<String>,
) -> Result<(Mapping, Vec<(String, String)>)> {
pub fn use_script(script: String, config: Mapping) -> Result<(Mapping, Vec<(String, String)>)> {
use rquickjs::{Context, Func, Runtime};
use std::sync::{Arc, Mutex};
@@ -33,25 +29,32 @@ pub fn use_script(
});"#,
)?;
let config = use_lowercase(config.clone());
let config_str = serde_json::to_string(&config)?;
let code = format!("\n{script}\n;\nJSON.stringify(main({config_str})||'')");
let code = format!(
r#"try{{
{script}\n;
JSON.stringify(main({config_str})||'')
}} catch(err) {{
`__error_flag__ ${{err.toString()}}`
}}"#
);
let result: String = ctx.eval(code.as_str())?;
// if result.starts_with("__error_flag__") {
// anyhow::bail!(result.slice_unchecked(begin, end));
// }
if result == "\"\"" {
anyhow::bail!("main function should return object");
}
Ok(serde_json::from_str::<Mapping>(result.as_str())?)
return Ok(serde_json::from_str::<Mapping>(result.as_str())?);
});
let mut out = outputs.lock().unwrap();
match result {
Ok(config) => {
let valid = use_valid_fields(valid);
let config = use_filter(config, valid);
Ok((config, out.to_vec()))
}
Ok(config) => Ok((use_lowercase(config), out.to_vec())),
Err(err) => {
out.push(("error".into(), err.to_string()));
out.push(("exception".into(), err.to_string()));
Ok((config, out.to_vec()))
}
}
@@ -81,12 +84,7 @@ fn test_script() {
"#;
let config = serde_yaml::from_str(config).unwrap();
let (config, results) = use_script(
script.into(),
config,
vec!["tun"].iter().map(|s| s.to_string()).collect(),
)
.unwrap();
let (config, results) = use_script(script.into(), config).unwrap();
let config_str = serde_yaml::to_string(&config).unwrap();