garbage-code-hunter 0.2.0

A humorous Rust code quality detector that roasts your garbage code
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
/// Educational advice system that provides detailed explanations and improvement suggestions
use std::collections::HashMap;

#[derive(Debug, Clone)]
pub struct EducationalAdvice {
    pub why_bad: String,
    pub how_to_fix: String,
    pub best_practice_tip: Option<String>,
}

pub struct EducationalAdvisor {
    advice_db: HashMap<String, EducationalAdvice>,
    lang: String,
}

impl EducationalAdvisor {
    pub fn new(lang: &str) -> Self {
        let mut advisor = Self {
            advice_db: HashMap::new(),
            lang: lang.to_string(),
        };
        advisor.initialize_advice_database();
        advisor
    }

    pub fn get_advice(&self, rule_name: &str) -> Option<&EducationalAdvice> {
        self.advice_db.get(rule_name)
    }

    fn initialize_advice_database(&mut self) {
        // Naming convention advice
        self.add_advice("terrible-naming", self.create_terrible_naming_advice());
        self.add_advice(
            "meaningless-naming",
            self.create_meaningless_naming_advice(),
        );
        self.add_advice(
            "hungarian-notation",
            self.create_hungarian_notation_advice(),
        );
        self.add_advice(
            "abbreviation-abuse",
            self.create_abbreviation_abuse_advice(),
        );

        // Complexity advice
        self.add_advice("deep-nesting", self.create_deep_nesting_advice());
        self.add_advice("god-function", self.create_god_function_advice());
        self.add_advice("long-function", self.create_long_function_advice());

        // Code smells advice
        self.add_advice("magic-number", self.create_magic_number_advice());
        self.add_advice("commented-code", self.create_commented_code_advice());
        self.add_advice("dead-code", self.create_dead_code_advice());

        // Rust-specific advice
        self.add_advice("unwrap-abuse", self.create_unwrap_abuse_advice());
        self.add_advice("string-abuse", self.create_string_abuse_advice());
        self.add_advice("unnecessary-clone", self.create_unnecessary_clone_advice());
        self.add_advice("iterator-abuse", self.create_iterator_abuse_advice());

        // Student code advice
        self.add_advice("println-debugging", self.create_println_debugging_advice());
        self.add_advice("panic-abuse", self.create_panic_abuse_advice());
        self.add_advice("todo-comment", self.create_todo_comment_advice());

        // File structure advice
        self.add_advice("file-too-long", self.create_file_too_long_advice());
        self.add_advice("unordered-imports", self.create_unordered_imports_advice());
        self.add_advice(
            "deep-module-nesting",
            self.create_deep_module_nesting_advice(),
        );
    }

    fn add_advice(&mut self, rule_name: &str, advice: EducationalAdvice) {
        self.advice_db.insert(rule_name.to_string(), advice);
    }

    fn create_terrible_naming_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "糟糕的变量命名会严重影响代码可读性,让其他开发者(包括未来的你)难以理解代码意图。".to_string(),
                how_to_fix: "使用描述性的、有意义的变量名,清楚地表达变量的用途和含义。".to_string(),
                best_practice_tip: Some("变量名应该是自文档化的,读代码的人应该能从名字就理解变量的用途。".to_string()),
            }
        } else {
            EducationalAdvice {
                why_bad: "Poor variable naming severely impacts code readability, making it difficult for other developers (including future you) to understand the code's intent.".to_string(),
                how_to_fix: "Use descriptive, meaningful variable names that clearly express the variable's purpose and meaning.".to_string(),
                best_practice_tip: Some("Variable names should be self-documenting - readers should understand the purpose from the name alone.".to_string()),
            }
        }
    }

    fn create_meaningless_naming_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "使用 foo、bar、data、temp 等占位符命名会让代码失去表达力,增加维护成本。"
                    .to_string(),
                how_to_fix: "根据变量的实际用途选择具体的、有意义的名称。".to_string(),
                best_practice_tip: Some(
                    "避免使用通用词汇,选择能准确描述数据性质的词汇。".to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Using placeholder names like foo, bar, data, temp makes code lose expressiveness and increases maintenance cost.".to_string(),
                how_to_fix: "Choose specific, meaningful names based on the variable's actual purpose.".to_string(),
                best_practice_tip: Some("Avoid generic words, choose words that accurately describe the nature of the data.".to_string()),
            }
        }
    }

    fn create_hungarian_notation_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad:
                    "匈牙利命名法在现代编程语言中已经过时,Rust 的类型系统已经提供了类型安全保障。"
                        .to_string(),
                how_to_fix: "使用描述性名称而不是类型前缀,让 Rust 的类型系统处理类型检查。"
                    .to_string(),
                best_practice_tip: Some(
                    "Rust 的强类型系统使得类型前缀变得多余,专注于语义而非类型。".to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Hungarian notation is outdated in modern programming languages, Rust's type system already provides type safety guarantees.".to_string(),
                how_to_fix: "Use descriptive names instead of type prefixes, let Rust's type system handle type checking.".to_string(),
                best_practice_tip: Some("Rust's strong type system makes type prefixes redundant, focus on semantics rather than types.".to_string()),
            }
        }
    }

    fn create_abbreviation_abuse_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "过度缩写会让代码变得难以理解,特别是对新团队成员或几个月后的自己。"
                    .to_string(),
                how_to_fix: "使用完整的、清晰的单词,现代编辑器的自动补全让长名称不再是问题。"
                    .to_string(),
                best_practice_tip: Some(
                    "清晰胜过简洁,代码被阅读的次数远超过被编写的次数。".to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Excessive abbreviations make code hard to understand, especially for new team members or yourself months later.".to_string(),
                how_to_fix: "Use complete, clear words. Modern editors' auto-completion makes long names no longer a problem.".to_string(),
                best_practice_tip: Some("Clarity over brevity - code is read far more often than it's written.".to_string()),
            }
        }
    }

    fn create_deep_nesting_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "深层嵌套增加了代码的认知复杂度,使得逻辑难以跟踪和调试。".to_string(),
                how_to_fix: "使用早期返回、提取函数、或者 Rust 的 ? 操作符来减少嵌套层级。"
                    .to_string(),
                best_practice_tip: Some(
                    "保持嵌套层级在 3 层以内,使用卫语句和早期返回。".to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Deep nesting increases cognitive complexity, making logic hard to follow and debug.".to_string(),
                how_to_fix: "Use early returns, extract functions, or Rust's ? operator to reduce nesting levels.".to_string(),
                best_practice_tip: Some("Keep nesting levels within 3, use guard clauses and early returns.".to_string()),
            }
        }
    }

    fn create_unwrap_abuse_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad:
                    "过度使用 unwrap() 会导致程序在遇到错误时直接崩溃,无法优雅地处理异常情况。"
                        .to_string(),
                how_to_fix: "使用 match、if let、或者 ? 操作符来正确处理 Option 和 Result 类型。"
                    .to_string(),
                best_practice_tip: Some(
                    "只在你确定不会失败的情况下使用 unwrap(),并添加注释说明原因。".to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Excessive use of unwrap() causes programs to crash directly when encountering errors, unable to handle exceptions gracefully.".to_string(),
                how_to_fix: "Use match, if let, or the ? operator to properly handle Option and Result types.".to_string(),
                best_practice_tip: Some("Only use unwrap() when you're certain it won't fail, and add comments explaining why.".to_string()),
            }
        }
    }

    fn create_string_abuse_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad:
                    "不必要的 String 分配会增加内存使用和性能开销,特别是在只需要读取的场景中。"
                        .to_string(),
                how_to_fix: "在只需要读取字符串的地方使用 &str,只在需要拥有所有权时使用 String。"
                    .to_string(),
                best_practice_tip: Some(
                    "优先使用 &str 作为函数参数,这样可以接受 String 和 &str 两种类型。"
                        .to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Unnecessary String allocations increase memory usage and performance overhead, especially in read-only scenarios.".to_string(),
                how_to_fix: "Use &str where you only need to read strings, use String only when you need ownership.".to_string(),
                best_practice_tip: Some("Prefer &str as function parameters, this way you can accept both String and &str types.".to_string()),
            }
        }
    }

    fn create_println_debugging_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "遗留的 println! 调试语句会污染输出,在生产环境中可能泄露敏感信息。"
                    .to_string(),
                how_to_fix: "使用 log 库进行日志记录,或者使用 dbg! 宏进行临时调试(记得删除)。"
                    .to_string(),
                best_practice_tip: Some(
                    "使用条件编译 #[cfg(debug_assertions)] 来确保调试代码不会进入生产环境。"
                        .to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Leftover println! debug statements pollute output and may leak sensitive information in production.".to_string(),
                how_to_fix: "Use the log crate for logging, or use the dbg! macro for temporary debugging (remember to remove).".to_string(),
                best_practice_tip: Some("Use conditional compilation #[cfg(debug_assertions)] to ensure debug code doesn't reach production.".to_string()),
            }
        }
    }

    fn create_file_too_long_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "过长的文件难以导航和维护,违反了单一职责原则,增加了代码复杂度。"
                    .to_string(),
                how_to_fix: "将大文件拆分成多个小模块,每个模块负责特定的功能领域。".to_string(),
                best_practice_tip: Some(
                    "保持文件在 500-1000 行以内,超出时考虑按功能拆分。".to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Overly long files are hard to navigate and maintain, violate the single responsibility principle, and increase code complexity.".to_string(),
                how_to_fix: "Split large files into multiple small modules, each responsible for specific functional areas.".to_string(),
                best_practice_tip: Some("Keep files within 500-1000 lines, consider splitting by functionality when exceeded.".to_string()),
            }
        }
    }

    // Add more advice creation methods for other rules...
    fn create_god_function_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "做太多事情的函数违反了单一职责原则,难以测试和维护。".to_string(),
                how_to_fix: "将大函数拆分成更小的、专注的函数,每个函数只做一件事。".to_string(),
                best_practice_tip: Some("保持函数在 20-30 行以内,专注于单一任务。".to_string()),
            }
        } else {
            EducationalAdvice {
                why_bad: "Functions that do too much violate the single responsibility principle and are hard to test and maintain.".to_string(),
                how_to_fix: "Break down large functions into smaller, focused functions that each do one thing well.".to_string(),
                best_practice_tip: Some("Keep functions under 20-30 lines and focused on a single task.".to_string()),
            }
        }
    }

    fn create_long_function_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "长函数更难理解、测试和维护。".to_string(),
                how_to_fix: "将逻辑块提取到具有描述性名称的独立函数中。".to_string(),
                best_practice_tip: Some(
                    "如果你无法在屏幕上看到整个函数,那它可能太长了。".to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Long functions are harder to understand, test, and maintain.".to_string(),
                how_to_fix:
                    "Extract logical blocks into separate functions with descriptive names."
                        .to_string(),
                best_practice_tip: Some(
                    "If you can't see the entire function on your screen, it's probably too long."
                        .to_string(),
                ),
            }
        }
    }

    fn create_magic_number_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "魔法数字让代码难以理解和维护。".to_string(),
                how_to_fix: "用能解释其用途的命名常量替换魔法数字。".to_string(),
                best_practice_tip: Some("对具有语义含义的值使用 const 声明。".to_string()),
            }
        } else {
            EducationalAdvice {
                why_bad: "Magic numbers make code hard to understand and maintain.".to_string(),
                how_to_fix:
                    "Replace magic numbers with named constants that explain their purpose."
                        .to_string(),
                best_practice_tip: Some(
                    "Use const declarations for values that have semantic meaning.".to_string(),
                ),
            }
        }
    }

    fn create_commented_code_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "注释掉的代码会污染代码库,让人困惑哪些是真正在使用的代码。".to_string(),
                how_to_fix: "删除注释掉的代码 - 版本控制系统会保留历史记录。".to_string(),
                best_practice_tip: Some(
                    "相信你的版本控制系统 - 删除死代码而不是注释掉它。".to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Commented-out code clutters the codebase and creates confusion about what's actually used.".to_string(),
                how_to_fix: "Remove commented code - version control systems preserve history.".to_string(),
                best_practice_tip: Some("Trust your version control system - delete dead code instead of commenting it out.".to_string()),
            }
        }
    }

    fn create_dead_code_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "死代码增加了维护负担,会让开发者困惑。".to_string(),
                how_to_fix: "定期删除未使用的函数、变量和导入。".to_string(),
                best_practice_tip: Some("使用 cargo clippy 自动检测死代码。".to_string()),
            }
        } else {
            EducationalAdvice {
                why_bad: "Dead code increases maintenance burden and can confuse developers."
                    .to_string(),
                how_to_fix: "Remove unused functions, variables, and imports regularly."
                    .to_string(),
                best_practice_tip: Some(
                    "Use cargo clippy to detect dead code automatically.".to_string(),
                ),
            }
        }
    }

    fn create_unnecessary_clone_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "不必要的 clone 会浪费内存和 CPU 周期。".to_string(),
                how_to_fix: "尽可能使用引用,只在需要所有权时才 clone。".to_string(),
                best_practice_tip: Some("理解 Rust 的借用规则以减少不必要的分配。".to_string()),
            }
        } else {
            EducationalAdvice {
                why_bad: "Unnecessary clones waste memory and CPU cycles.".to_string(),
                how_to_fix: "Use references when possible, clone only when you need ownership."
                    .to_string(),
                best_practice_tip: Some(
                    "Understand Rust's borrowing rules to minimize unnecessary allocations."
                        .to_string(),
                ),
            }
        }
    }

    fn create_iterator_abuse_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "手动循环通常比迭代器链更低效且表达力差。".to_string(),
                how_to_fix: "在适当的情况下使用 map、filter、fold 等迭代器方法代替手动循环。"
                    .to_string(),
                best_practice_tip: Some(
                    "迭代器链由于惰性求值和编译器优化,通常更高效。".to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Manual loops are often less efficient and expressive than iterator chains.".to_string(),
                how_to_fix: "Use iterator methods like map, filter, fold instead of manual loops when appropriate.".to_string(),
                best_practice_tip: Some("Iterator chains are often more efficient due to lazy evaluation and compiler optimizations.".to_string()),
            }
        }
    }

    fn create_panic_abuse_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "过度使用 panic 会让程序在生产环境中不可靠且难以调试。".to_string(),
                how_to_fix: "对可恢复的错误使用 Result 类型,仅在真正无法恢复的情况下使用 panic。"
                    .to_string(),
                best_practice_tip: Some(
                    "Panic 应该用于编程错误,而不是预期的错误条件。".to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Excessive panics make programs unreliable and hard to debug in production.".to_string(),
                how_to_fix: "Use Result types for recoverable errors, reserve panics for truly unrecoverable situations.".to_string(),
                best_practice_tip: Some("Panics should be used for programming errors, not for expected error conditions.".to_string()),
            }
        }
    }

    fn create_todo_comment_advice(&self) -> EducationalAdvice {
        if self.lang == "zh-CN" {
            EducationalAdvice {
                why_bad: "过多的 TODO 注释表示代码不完整或规划不当。".to_string(),
                how_to_fix: "要么实现这些 TODO,要么为未来的工作创建适当的问题跟踪。".to_string(),
                best_practice_tip: Some(
                    "谨慎使用 TODO,并始终附带具体的解决方案计划。".to_string(),
                ),
            }
        } else {
            EducationalAdvice {
                why_bad: "Too many TODO comments indicate incomplete or poorly planned code."
                    .to_string(),
                how_to_fix:
                    "Either implement the TODOs or create proper issue tracking for future work."
                        .to_string(),
                best_practice_tip: Some(
                    "Use TODO sparingly and always with a specific plan for resolution."
                        .to_string(),
                ),
            }
        }
    }

    fn create_unordered_imports_advice(&self) -> EducationalAdvice {
        EducationalAdvice {
            why_bad: "Unordered imports make it hard to find and manage dependencies.".to_string(),
            how_to_fix: "Use rustfmt to automatically sort imports, or sort them manually by: std, external crates, local modules.".to_string(),
            best_practice_tip: Some("Configure your editor to run rustfmt on save to maintain consistent formatting.".to_string()),
        }
    }

    fn create_deep_module_nesting_advice(&self) -> EducationalAdvice {
        EducationalAdvice {
            why_bad: "Deep module nesting makes code navigation difficult and indicates poor architecture.".to_string(),
            how_to_fix: "Flatten module structure, use re-exports to maintain clean public APIs.".to_string(),
            best_practice_tip: Some("Keep module nesting to 2-3 levels maximum, use re-exports for convenience.".to_string()),
        }
    }
}