use serde_yaml::{Mapping, Value}; pub const HANDLE_FIELDS: [&str; 9] = [ "port", "socks-port", "mixed-port", "mode", "ipv6", "log-level", "allow-lan", "external-controller", "secret", ]; pub const DEFAULT_FIELDS: [&str; 5] = [ "proxies", "proxy-groups", "rules", "proxy-providers", "rule-providers", ]; pub const OTHERS_FIELDS: [&str; 21] = [ "tun", "dns", "ebpf", "hosts", "script", "profile", "payload", "auto-redir", "experimental", "interface-name", "routing-mark", "redir-port", "tproxy-port", "iptables", "external-ui", "bind-address", "authentication", "sniffer", // meta "sub-rules", // meta "geodata-mode", // meta "tcp-concurrent", // meta ]; pub fn use_clash_fields() -> Vec<String> { DEFAULT_FIELDS .into_iter() .chain(HANDLE_FIELDS) .chain(OTHERS_FIELDS) .map(|s| s.to_string()) .collect() } pub fn use_valid_fields(mut valid: Vec<String>) -> Vec<String> { let others = Vec::from(OTHERS_FIELDS); valid.iter_mut().for_each(|s| s.make_ascii_lowercase()); valid .into_iter() .filter(|s| others.contains(&s.as_str())) .chain(DEFAULT_FIELDS.iter().map(|s| s.to_string())) .collect() } pub fn use_filter(config: Mapping, filter: &Vec<String>) -> Mapping { let mut ret = Mapping::new(); for (key, value) in config.into_iter() { 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(); ret.insert(Value::from(key_str), value); } } ret } pub fn use_sort(config: Mapping) -> Mapping { let mut ret = Mapping::new(); HANDLE_FIELDS .into_iter() .chain(OTHERS_FIELDS) .chain(DEFAULT_FIELDS) .for_each(|key| { let key = Value::from(key); config.get(&key).map(|value| { ret.insert(key, value.clone()); }); }); 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() }