rust_diff_analyzer/classifier/
rules.rs

1// SPDX-FileCopyrightText: 2025 RAprogramm <andrey.rozanov.vl@gmail.com>
2// SPDX-License-Identifier: MIT
3
4use crate::{
5    config::Config,
6    types::{SemanticUnit, SemanticUnitKind},
7};
8
9/// Calculates the weight score for a semantic unit
10///
11/// # Arguments
12///
13/// * `unit` - Semantic unit to calculate weight for
14/// * `config` - Configuration with weight settings
15///
16/// # Returns
17///
18/// Weight score for the unit
19///
20/// # Examples
21///
22/// ```
23/// use rust_diff_analyzer::{
24///     classifier::rules::calculate_weight,
25///     config::Config,
26///     types::{LineSpan, SemanticUnit, SemanticUnitKind, Visibility},
27/// };
28///
29/// let unit = SemanticUnit::new(
30///     SemanticUnitKind::Function,
31///     "public_fn".to_string(),
32///     Visibility::Public,
33///     LineSpan::new(1, 10),
34///     vec![],
35/// );
36///
37/// let config = Config::default();
38/// let weight = calculate_weight(&unit, &config);
39/// assert_eq!(weight, 3); // default public function weight
40/// ```
41pub fn calculate_weight(unit: &SemanticUnit, config: &Config) -> usize {
42    let weights = &config.weights;
43
44    match unit.kind {
45        SemanticUnitKind::Function => {
46            if unit.visibility.is_public() {
47                weights.public_function
48            } else {
49                weights.private_function
50            }
51        }
52        SemanticUnitKind::Struct | SemanticUnitKind::Enum => {
53            if unit.visibility.is_public() {
54                weights.public_struct
55            } else {
56                weights.private_struct
57            }
58        }
59        SemanticUnitKind::Impl => weights.impl_block,
60        SemanticUnitKind::Trait => weights.trait_definition,
61        SemanticUnitKind::Const | SemanticUnitKind::Static => weights.const_static,
62        SemanticUnitKind::TypeAlias => weights.const_static,
63        SemanticUnitKind::Macro => weights.private_function,
64        SemanticUnitKind::Module => weights.const_static,
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71    use crate::types::{LineSpan, Visibility};
72
73    #[test]
74    fn test_weight_calculation() {
75        let config = Config::default();
76
77        let pub_fn = SemanticUnit::new(
78            SemanticUnitKind::Function,
79            "public".to_string(),
80            Visibility::Public,
81            LineSpan::new(1, 10),
82            vec![],
83        );
84        assert_eq!(calculate_weight(&pub_fn, &config), 3);
85
86        let priv_fn = SemanticUnit::new(
87            SemanticUnitKind::Function,
88            "private".to_string(),
89            Visibility::Private,
90            LineSpan::new(1, 10),
91            vec![],
92        );
93        assert_eq!(calculate_weight(&priv_fn, &config), 1);
94
95        let trait_def = SemanticUnit::new(
96            SemanticUnitKind::Trait,
97            "MyTrait".to_string(),
98            Visibility::Public,
99            LineSpan::new(1, 10),
100            vec![],
101        );
102        assert_eq!(calculate_weight(&trait_def, &config), 4);
103    }
104}