devalang_wasm/tools/logger/
rule_checker.rs

1/// Rule-based logging system for handling code quality rules
2///
3/// This module provides a system for enforcing coding rules at different severity levels:
4/// - Error: Compilation should fail
5/// - Warning: Compilation continues but warning is shown
6/// - Info: Informational message only
7/// - Off: Rule is disabled
8use crate::platform::config::{AppConfig, RuleLevel};
9
10pub struct RuleChecker {
11    config: AppConfig,
12}
13
14impl RuleChecker {
15    /// Create a new rule checker from configuration
16    pub fn new(config: AppConfig) -> Self {
17        Self { config }
18    }
19
20    /// Check if explicit durations are required
21    pub fn check_explicit_duration(
22        &self,
23        line_number: usize,
24        context: &str,
25    ) -> Option<RuleMessage> {
26        let level = self.config.rules.explicit_durations;
27        if !level.should_report() {
28            return None;
29        }
30
31        Some(RuleMessage {
32            level,
33            rule_name: "explicit_durations",
34            message: format!(
35                "Line {}: Duration not explicitly specified. {}",
36                line_number, context
37            ),
38        })
39    }
40
41    /// Check if deprecated syntax is used
42    pub fn check_deprecated_syntax(
43        &self,
44        line_number: usize,
45        old_syntax: &str,
46        new_syntax: &str,
47    ) -> Option<RuleMessage> {
48        let level = self.config.rules.deprecated_syntax;
49        if !level.should_report() {
50            return None;
51        }
52
53        Some(RuleMessage {
54            level,
55            rule_name: "deprecated_syntax",
56            message: format!(
57                "Line {}: '{}' is deprecated, use '{}' instead",
58                line_number, old_syntax, new_syntax
59            ),
60        })
61    }
62
63    /// Check if 'var' keyword is used
64    pub fn check_var_keyword(&self, line_number: usize) -> Option<RuleMessage> {
65        let level = self.config.rules.var_keyword;
66        if !level.should_report() {
67            return None;
68        }
69
70        Some(RuleMessage {
71            level,
72            rule_name: "var_keyword",
73            message: format!(
74                "Line {}: 'var' keyword is not allowed, use 'let' instead",
75                line_number
76            ),
77        })
78    }
79
80    /// Check for missing duration
81    pub fn check_missing_duration(&self, line_number: usize, element: &str) -> Option<RuleMessage> {
82        let level = self.config.rules.missing_duration;
83        if !level.should_report() {
84            return None;
85        }
86
87        Some(RuleMessage {
88            level,
89            rule_name: "missing_duration",
90            message: format!(
91                "Line {}: '{}' might benefit from an explicit duration",
92                line_number, element
93            ),
94        })
95    }
96
97    /// Check for implicit type conversion
98    pub fn check_implicit_conversion(
99        &self,
100        line_number: usize,
101        from_type: &str,
102        to_type: &str,
103    ) -> Option<RuleMessage> {
104        let level = self.config.rules.implicit_type_conversion;
105        if !level.should_report() {
106            return None;
107        }
108
109        Some(RuleMessage {
110            level,
111            rule_name: "implicit_type_conversion",
112            message: format!(
113                "Line {}: Implicit conversion from '{}' to '{}'. Consider explicit conversion",
114                line_number, from_type, to_type
115            ),
116        })
117    }
118
119    /// Check for unused variables
120    pub fn check_unused_variable(&self, line_number: usize, var_name: &str) -> Option<RuleMessage> {
121        let level = self.config.rules.unused_variables;
122        if !level.should_report() {
123            return None;
124        }
125
126        Some(RuleMessage {
127            level,
128            rule_name: "unused_variables",
129            message: format!(
130                "Line {}: Variable '{}' is defined but never used",
131                line_number, var_name
132            ),
133        })
134    }
135}
136
137/// A rule violation message with associated severity level
138#[derive(Debug, Clone)]
139pub struct RuleMessage {
140    pub level: RuleLevel,
141    pub rule_name: &'static str,
142    pub message: String,
143}
144
145impl RuleMessage {
146    /// Format the message for display with level indicator
147    pub fn formatted(&self) -> String {
148        let level_str = match self.level {
149            RuleLevel::Error => "ERROR",
150            RuleLevel::Warning => "WARNING",
151            RuleLevel::Info => "INFO",
152            RuleLevel::Off => "OFF",
153        };
154
155        format!("[{}] {}: {}", level_str, self.rule_name, self.message)
156    }
157
158    /// Get the ANSI color code for the level
159    pub fn color_code(&self) -> &'static str {
160        match self.level {
161            RuleLevel::Error => "\x1b[91m",   // Bright red
162            RuleLevel::Warning => "\x1b[93m", // Bright yellow
163            RuleLevel::Info => "\x1b[94m",    // Bright blue
164            RuleLevel::Off => "\x1b[37m",     // White
165        }
166    }
167
168    /// Get the reset color code
169    pub fn reset_color() -> &'static str {
170        "\x1b[0m"
171    }
172
173    /// Format with ANSI colors
174    pub fn colored(&self) -> String {
175        format!(
176            "{}{}{}",
177            self.color_code(),
178            self.formatted(),
179            Self::reset_color()
180        )
181    }
182}