darklua_core/rules/
unused_while.rs1use crate::nodes::{Block, Statement};
2use crate::process::{DefaultVisitor, Evaluator, NodeProcessor, NodeVisitor};
3use crate::rules::{
4 Context, FlawlessRule, RuleConfiguration, RuleConfigurationError, RuleMetadata, RuleProperties,
5};
6
7use super::verify_no_rule_properties;
8
9#[derive(Debug, Clone, Default)]
10struct WhileFilter {
11 evaluator: Evaluator,
12}
13
14impl NodeProcessor for WhileFilter {
15 fn process_block(&mut self, block: &mut Block) {
16 block.filter_statements(|statement| match statement {
17 Statement::While(while_statement) => {
18 let condition = while_statement.get_condition();
19
20 self.evaluator.has_side_effects(condition)
21 || self
22 .evaluator
23 .evaluate(condition)
24 .is_truthy()
25 .unwrap_or(true)
26 }
27 _ => true,
28 });
29 }
30}
31
32pub const REMOVE_UNUSED_WHILE_RULE_NAME: &str = "remove_unused_while";
33
34#[derive(Debug, Default, PartialEq, Eq)]
36pub struct RemoveUnusedWhile {
37 metadata: RuleMetadata,
38}
39
40impl FlawlessRule for RemoveUnusedWhile {
41 fn flawless_process(&self, block: &mut Block, _: &Context) {
42 let mut processor = WhileFilter::default();
43 DefaultVisitor::visit_block(block, &mut processor);
44 }
45}
46
47impl RuleConfiguration for RemoveUnusedWhile {
48 fn configure(&mut self, properties: RuleProperties) -> Result<(), RuleConfigurationError> {
49 verify_no_rule_properties(&properties)?;
50
51 Ok(())
52 }
53
54 fn get_name(&self) -> &'static str {
55 REMOVE_UNUSED_WHILE_RULE_NAME
56 }
57
58 fn serialize_to_properties(&self) -> RuleProperties {
59 RuleProperties::new()
60 }
61
62 fn set_metadata(&mut self, metadata: RuleMetadata) {
63 self.metadata = metadata;
64 }
65
66 fn metadata(&self) -> &RuleMetadata {
67 &self.metadata
68 }
69}
70
71#[cfg(test)]
72mod test {
73 use super::*;
74 use crate::rules::Rule;
75
76 use insta::assert_json_snapshot;
77
78 fn new_rule() -> RemoveUnusedWhile {
79 RemoveUnusedWhile::default()
80 }
81
82 #[test]
83 fn serialize_default_rule() {
84 let rule: Box<dyn Rule> = Box::new(new_rule());
85
86 assert_json_snapshot!(rule, @r###""remove_unused_while""###);
87 }
88
89 #[test]
90 fn configure_with_extra_field_error() {
91 let result = json5::from_str::<Box<dyn Rule>>(
92 r#"{
93 rule: 'remove_unused_while',
94 prop: "something",
95 }"#,
96 );
97 insta::assert_snapshot!(result.unwrap_err().to_string(), @"unexpected field 'prop' at line 1 column 1");
98 }
99}