libsubconverter/settings/external/
toml_external.rs

1use serde::Deserialize;
2use std::collections::HashMap;
3
4use crate::models::{ProxyGroupConfigs, RegexMatchConfig, RulesetConfig};
5use crate::settings::import_toml::import_toml_items;
6use crate::settings::toml_deserializer::*;
7use crate::settings::Settings;
8use crate::utils::http::parse_proxy;
9
10// Default value functions
11fn default_true() -> bool {
12    true
13}
14
15/// Rule bases settings
16#[derive(Debug, Clone, Deserialize, Default)]
17#[serde(default)]
18pub struct RuleBasesSettings {
19    pub clash_rule_base: String,
20    pub surge_rule_base: String,
21    pub surfboard_rule_base: String,
22    pub mellow_rule_base: String,
23    pub quan_rule_base: String,
24    pub quanx_rule_base: String,
25    pub loon_rule_base: String,
26    pub sssub_rule_base: String,
27    pub singbox_rule_base: String,
28}
29
30/// Rule generation options
31#[derive(Debug, Clone, Deserialize, Default)]
32#[serde(default)]
33pub struct RuleGenerationSettings {
34    #[serde(default = "default_true")]
35    pub enable_rule_generator: bool,
36    pub overwrite_original_rules: bool,
37}
38
39/// Emoji settings
40#[derive(Debug, Clone, Deserialize, Default)]
41#[serde(default)]
42pub struct EmojiSettings {
43    pub add_emoji: Option<bool>,
44    pub remove_old_emoji: Option<bool>,
45    pub emoji: Vec<RegexMatchRuleInToml>,
46}
47
48/// Filtering settings
49#[derive(Debug, Clone, Deserialize, Default)]
50#[serde(default)]
51pub struct FilteringSettings {
52    pub include_remarks: Vec<String>,
53    pub exclude_remarks: Vec<String>,
54}
55
56/// Custom settings
57#[derive(Debug, Clone, Deserialize, Default)]
58#[serde(default)]
59pub struct CustomSettings {
60    // Include the custom settings from RuleBasesSettings
61    #[serde(flatten)]
62    pub rule_bases: RuleBasesSettings,
63
64    // Rule generation options
65    #[serde(flatten)]
66    pub rule_generation: RuleGenerationSettings,
67
68    // Emoji settings
69    #[serde(flatten)]
70    pub emoji_settings: EmojiSettings,
71
72    // Filtering settings
73    #[serde(flatten)]
74    pub filtering: FilteringSettings,
75
76    // Emoji and rename rules
77    pub rename_node: Vec<RegexMatchRuleInToml>,
78
79    // Custom rulesets and proxy groups
80    pub custom_rulesets: Vec<RulesetConfigInToml>,
81    pub custom_proxy_groups: Vec<ProxyGroupConfigInToml>,
82}
83
84/// Main TOML external settings structure
85#[derive(Debug, Clone, Deserialize, Default)]
86#[serde(default)]
87pub struct TomlExternalSettings {
88    pub custom: CustomSettings,
89    #[serde(deserialize_with = "deserialize_template_args_as_hash_map")]
90    pub tpl_args: Option<HashMap<String, String>>,
91
92    // Processed fields
93    #[serde(skip)]
94    pub parsed_custom_proxy_groups: ProxyGroupConfigs,
95    #[serde(skip)]
96    pub parsed_rulesets: Vec<RulesetConfig>,
97    #[serde(skip)]
98    pub parsed_rename: Vec<RegexMatchConfig>,
99    #[serde(skip)]
100    pub parsed_emojis: Vec<RegexMatchConfig>,
101}
102
103impl TomlExternalSettings {
104    pub async fn process_imports(&mut self) -> Result<(), Box<dyn std::error::Error>> {
105        let global = Settings::current();
106        let proxy_config = parse_proxy(&global.proxy_config);
107
108        import_toml_items(
109            &mut self.custom.rename_node,
110            false,
111            "rename_node",
112            &proxy_config,
113            &global.base_path,
114        )
115        .await?;
116        self.parsed_rename = self
117            .custom
118            .rename_node
119            .iter()
120            .map(|r| r.clone().into())
121            .collect();
122
123        // Process emoji rules
124        import_toml_items(
125            &mut self.custom.emoji_settings.emoji,
126            false,
127            "emoji",
128            &proxy_config,
129            &global.base_path,
130        )
131        .await?;
132        self.parsed_emojis = self
133            .custom
134            .emoji_settings
135            .emoji
136            .iter()
137            .map(|r| r.clone().into())
138            .collect();
139
140        // Process imports for rulesets
141        import_toml_items(
142            &mut self.custom.custom_rulesets,
143            global.api_mode,
144            "rulesets",
145            &proxy_config,
146            &global.base_path,
147        )
148        .await?;
149        if global.max_allowed_rulesets > 0
150            && self.custom.custom_rulesets.len() > global.max_allowed_rulesets
151        {
152            return Err(format!(
153                "Number of rulesets exceeds the maximum allowed: {}",
154                global.max_allowed_rulesets
155            )
156            .into());
157        }
158
159        self.parsed_rulesets = self
160            .custom
161            .custom_rulesets
162            .iter()
163            .map(|r| r.clone().into())
164            .collect();
165
166        // Process imports for proxy groups
167        import_toml_items(
168            &mut self.custom.custom_proxy_groups,
169            global.api_mode,
170            "custom_group",
171            &proxy_config,
172            &global.base_path,
173        )
174        .await?;
175        self.parsed_custom_proxy_groups = self
176            .custom
177            .custom_proxy_groups
178            .iter()
179            .map(|r| r.clone().into())
180            .collect();
181
182        Ok(())
183    }
184}