garbage_code_hunter/
utils.rs1use syn::spanned::Spanned;
2
3pub fn get_line_number<T: Spanned>(node: &T) -> usize {
5 node.span().start().line
6}
7
8pub fn get_column_number<T: Spanned>(node: &T) -> usize {
10 node.span().start().column + 1 }
12
13pub fn get_position<T: Spanned>(node: &T) -> (usize, usize) {
15 (get_line_number(node), get_column_number(node))
16}
17
18fn is_comment_line(trimmed: &str) -> bool {
20 trimmed.starts_with("///")
21 || trimmed.starts_with("//!")
22 || trimmed.starts_with("//")
23 || trimmed.starts_with("/*")
24 || trimmed.starts_with("*")
25}
26
27pub fn find_line_of_str(content: &str, target: &str) -> usize {
29 for (i, line) in content.lines().enumerate() {
30 let trimmed = line.trim();
31 if is_comment_line(trimmed) {
32 continue;
33 }
34 if line.contains(target) {
35 return i + 1;
36 }
37 }
38 1
39}
40
41pub fn find_line_of_str_non_import(content: &str, target: &str) -> usize {
43 for (i, line) in content.lines().enumerate() {
44 let trimmed = line.trim();
45 if is_comment_line(trimmed) || trimmed.starts_with("use ") {
46 continue;
47 }
48 if line.contains(target) {
49 return i + 1;
50 }
51 }
52 1
53}
54
55pub fn count_non_comment_matches(content: &str, target: &str) -> usize {
57 let mut count = 0;
58 for line in content.lines() {
59 let trimmed = line.trim();
60 if is_comment_line(trimmed) {
61 continue;
62 }
63 count += line.matches(target).count();
64 }
65 count
66}
67
68pub fn count_non_import_matches(content: &str, target: &str) -> usize {
70 let mut count = 0;
71 for line in content.lines() {
72 let trimmed = line.trim();
73 if is_comment_line(trimmed) || trimmed.starts_with("use ") {
74 continue;
75 }
76 count += line.matches(target).count();
77 }
78 count
79}