Skip to main content

rswappalyzer_engine/
processor.rs

1use crate::{
2    CoreResult, cleaner::RuleCleaner, core::{MatchScope, RuleLibrary, TechBasicInfo}, indexer::{CommonIndexedRule, RuleLibraryIndex, ScopedIndexedRule}
3};
4
5/// 规则处理器,核心职责:清洗规则 + 构建索引 + 统计调试
6#[derive(Default)]
7pub struct RuleProcessor;
8
9impl RuleProcessor {
10    // Embedded模式加载规则
11    pub fn load_embedded(&self) -> CoreResult<RuleLibrary> {
12        Ok(RuleLibrary::default())
13    }
14
15    /// 构建索引库
16    pub fn build_index(&self, rule_lib: &RuleLibrary) -> RuleLibraryIndex {
17        let mut index = RuleLibraryIndex::default();
18
19        // 辅助函数:判断是否为 KV 型作用域(Header/Meta/Cookie)
20        fn is_keyed_scope(scope: &MatchScope) -> bool {
21            matches!(scope, MatchScope::Header | MatchScope::Meta | MatchScope::Cookie)
22        }
23
24        for (tech_name, tech_rule) in &rule_lib.core_tech_map {
25            // 写入技术基础信息
26            let tech_info = TechBasicInfo::from(tech_rule);
27            index.tech_info_map.insert(tech_name.clone(), tech_info);
28
29            // 遍历 match_rules 构建索引
30            for (scope, rule_set) in &tech_rule.match_rules {
31                if is_keyed_scope(scope) {
32                    // KV 型规则:构建 ScopedIndexedRule::KV 变体
33                    for keyed_pat in &rule_set.keyed_patterns {
34                        let common_rule = CommonIndexedRule {
35                            tech: tech_name.clone(),
36                            match_type: keyed_pat.pattern.match_type.clone(),
37                            pattern: keyed_pat.pattern.clone(),
38                            condition: rule_set.condition.clone(),
39                        };
40
41                        let scoped_rule = ScopedIndexedRule::KV {
42                            common: common_rule,
43                            key: keyed_pat.key.clone(),
44                        };
45
46                        index.rules.entry(scope.clone()).or_default().push(scoped_rule);
47                    }
48                } else {
49                    // 列表型规则:构建 ScopedIndexedRule::Content 变体
50                    for pattern in &rule_set.list_patterns {
51                        let common_rule = CommonIndexedRule {
52                            tech: tech_name.clone(),
53                            match_type: pattern.match_type.clone(),
54                            pattern: pattern.clone(),
55                            condition: rule_set.condition.clone(),
56                        };
57
58                        let scoped_rule = ScopedIndexedRule::Content(common_rule);
59
60                        index.rules.entry(scope.clone()).or_default().push(scoped_rule);
61                    }
62                }
63            }
64        }
65
66        // 调试日志
67        let get_rule_count = |scope: &MatchScope| -> usize {
68            index.rules.get(scope).map_or(0, |rules| rules.len())
69        };
70
71        log::debug!(
72            "索引构建完成:URL={}, HTML={}, Script={}, ScriptSrc={}, Meta={}, Header={}, Cookie={}, Js={}",
73            get_rule_count(&MatchScope::Url),
74            get_rule_count(&MatchScope::Html),
75            get_rule_count(&MatchScope::Script),
76            get_rule_count(&MatchScope::ScriptSrc),
77            get_rule_count(&MatchScope::Meta),
78            get_rule_count(&MatchScope::Header),
79            get_rule_count(&MatchScope::Cookie),
80            get_rule_count(&MatchScope::Js),
81        );
82
83        index
84    }
85
86    /// 清理并构建索引
87    pub fn clean_and_split_rules(&self, rule_lib: &RuleLibrary) -> CoreResult<RuleLibrary> {
88        let cleaner = RuleCleaner::default();
89        let cleaned_rule_lib = cleaner.clean(rule_lib)?;
90        self.build_index(&cleaned_rule_lib);
91        Ok(cleaned_rule_lib)
92    }
93
94    /// Script 规则统计
95    pub fn debug_count_script_rules(&self, rule_lib: &RuleLibrary) {
96        let mut has_script = 0;
97        let mut has_script_src = 0;
98        let mut script_patterns = 0;
99        let mut script_src_patterns = 0;
100    
101        for tech_rule in rule_lib.core_tech_map.values() {
102            if let Some(rule_set) = tech_rule.match_rules.get(&MatchScope::Script) {
103                has_script += 1;
104                script_patterns += rule_set.list_patterns.len();
105            }
106    
107            if let Some(rule_set) = tech_rule.match_rules.get(&MatchScope::ScriptSrc) {
108                has_script_src += 1;
109                script_src_patterns += rule_set.list_patterns.len();
110            }
111        }
112    
113        log::debug!("===== Script 规则统计 =====");
114        log::debug!("  技术规则总数:{}", rule_lib.core_tech_map.len());
115        log::debug!("  有 Script 的技术数:{}", has_script);
116        log::debug!("  有 ScriptSrc 的技术数:{}", has_script_src);
117        log::debug!("  Script 规则数:{}", script_patterns);
118        log::debug!("  ScriptSrc 规则数:{}", script_src_patterns);
119        log::debug!("  脚本规则总数:{}", script_patterns + script_src_patterns);
120    }
121
122}