libsubconverter/settings/external/
external_struct.rs1use serde_yaml;
2use std::collections::HashMap;
3use toml;
4
5use crate::models::{ProxyGroupConfig, RegexMatchConfig, RulesetConfig};
6use crate::settings::Settings;
7use crate::utils::file::load_content_async;
8use super::ini_external::IniExternalSettings;
11use super::toml_external::TomlExternalSettings;
12use super::yaml_external::YamlExternalSettings;
13
14#[derive(Debug, Clone, Default)]
16pub struct ExternalSettings {
17 pub clash_rule_base: String,
19 pub surge_rule_base: String,
20 pub surfboard_rule_base: String,
21 pub mellow_rule_base: String,
22 pub quan_rule_base: String,
23 pub quanx_rule_base: String,
24 pub loon_rule_base: String,
25 pub sssub_rule_base: String,
26 pub singbox_rule_base: String,
27
28 pub enable_rule_generator: Option<bool>,
30 pub overwrite_original_rules: Option<bool>,
31
32 pub add_emoji: Option<bool>,
34 pub remove_old_emoji: Option<bool>,
35 pub emojis: Vec<RegexMatchConfig>,
36
37 pub include_remarks: Vec<String>,
39 pub exclude_remarks: Vec<String>,
40 pub custom_rulesets: Vec<RulesetConfig>,
42 pub custom_proxy_groups: Vec<ProxyGroupConfig>,
43
44 pub rename_nodes: Vec<RegexMatchConfig>,
46
47 pub tpl_args: Option<HashMap<String, String>>,
49}
50
51impl ExternalSettings {
52 pub fn new() -> Self {
53 Self::default()
54 }
55
56 pub async fn load_from_file(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
66 let _content = load_content_async(path).await?;
68
69 Self::parse_content(&_content).await
70 }
71
72 async fn parse_content(content: &str) -> Result<Self, Box<dyn std::error::Error>> {
74 if content.contains("custom:") {
80 let mut yaml_settings: YamlExternalSettings = serde_yaml::from_str(content)?;
81 yaml_settings.process_imports().await?;
82 let config = Self::from(yaml_settings);
84 return Ok(config);
85 }
86
87 if toml::from_str::<toml::Value>(content).is_ok() {
88 let mut toml_settings: TomlExternalSettings = toml::from_str(content)?;
89 toml_settings.process_imports().await?;
90 let config = Self::from(toml_settings);
92 return Ok(config);
93 }
94
95 let mut ini_settings = IniExternalSettings::new();
97 match ini_settings.load_from_ini(content) {
98 Ok(_) => {
99 ini_settings.process_imports().await?;
101 let config = Self::from(ini_settings);
103 return Ok(config);
104 }
105 Err(e) => Err(format!("Failed to parse external config as INI: {}", e).into()),
106 }
107 }
108
109 pub fn validate_rulesets(&self) -> Result<(), Box<dyn std::error::Error>> {
111 let settings = Settings::current();
112 if settings.max_allowed_rulesets > 0
113 && self.custom_rulesets.len() > settings.max_allowed_rulesets
114 {
115 return Err("Ruleset count in external config has exceeded limit.".into());
116 }
117 Ok(())
118 }
119}