gather_all_code_from_crates/remove_unwanted_lines.rs
1crate::ix!();
2
3/// Removes doc comment lines (`///` or `//!`) if `remove_doc_comments = true`.
4/// Keeps all other lines intact, including attributes (`#[...]`), normal `//` comments,
5/// indentation, and whitespace. No inline truncation or other modifications are made.
6pub fn new_filter_lines(s: String, remove_doc_comments: bool) -> String {
7 let mut filtered = Vec::new();
8 for line in s.lines() {
9 let trimmed = line.trim_start();
10
11 // If requested to remove doc comments, skip lines starting with `///` or `//!`
12 if remove_doc_comments && (trimmed.starts_with("///") || trimmed.starts_with("//!")) {
13 continue;
14 }
15
16 // Keep everything else intact
17 filtered.push(line);
18 }
19
20 filtered.join("\n")
21}
22
23pub fn filter_lines(raw_signature: String, remove_doc_comments: bool) -> String {
24 if remove_doc_comments {
25 remove_unwanted_lines(raw_signature)
26 } else {
27 remove_unwanted_lines_keep_docs(raw_signature)
28 }
29}
30
31/// Removes all doc comments (`///`, `//!`), attribute lines (`#[...]`), and normal `//` comments
32/// when `remove_doc_comments = true`. Also handles inline `//` in code lines by truncation, preserving whitespace.
33pub fn remove_unwanted_lines(s: String) -> String {
34 let mut filtered = Vec::new();
35
36 for line in s.lines() {
37 let trimmed = line.trim_start();
38
39 // Identify line type:
40 // 1. Attribute line starts with `#[`
41 if trimmed.starts_with("#[") {
42 // Remove entire line
43 continue;
44 }
45
46 // 2. Doc lines `///` or `//!`
47 if trimmed.starts_with("///") || trimmed.starts_with("//!") {
48 // remove_doc_comments=true means remove doc lines entirely
49 continue;
50 }
51
52 // 3. Normal `//` lines (with no code) - remove entirely
53 // A normal `//` line is one that starts with `//` but is not doc line.
54 // Since doc lines are already handled, if it starts with `//` here, it's a normal comment line.
55 if trimmed.starts_with("//") {
56 // remove entire normal `//` line
57 continue;
58 }
59
60 // 4. Inline `//` in code lines:
61 // If there's a `//` somewhere after code, truncate the line at `//`.
62 if let Some(idx) = line.find("//") {
63 // Keep indentation and code before `//`
64 let code_part = &line[..idx];
65 // If code_part is all whitespace (meaning line was effectively a comment?), skip if needed.
66 // But here we have code line with inline comment. Keep code_part even if it's whitespace,
67 // since the user wants whitespace preserved.
68 let trimmed_code_part = code_part;
69 // Only add if something remains after truncation
70 if !trimmed_code_part.is_empty() {
71 filtered.push(trimmed_code_part);
72 } else {
73 // If after truncation nothing remains, it means the line was basically empty or just spaces before `//`.
74 // remove_doc_comments=true means we remove this line, as it's effectively a comment line.
75 continue;
76 }
77 } else {
78 // No `//` found, keep the line as is
79 filtered.push(line);
80 }
81 }
82
83 filtered.join("\n")
84}
85
86/// Removes attribute lines (`#[...]`) and normal `//` comment lines, but keeps doc lines (`///`, `//!`)
87/// when `remove_doc_comments = false`. Also handles inline `//` in code lines by truncation, preserving whitespace.
88///
89/// Doc lines are kept intact. Inline `//` in code lines still gets truncated.
90pub fn remove_unwanted_lines_keep_docs(s: String) -> String {
91 let mut filtered = Vec::new();
92
93 for line in s.lines() {
94 let trimmed = line.trim_start();
95
96 // Attribute lines:
97 if trimmed.starts_with("#[") {
98 // Remove entire line
99 continue;
100 }
101
102 // Normal `//` comment lines (not doc lines):
103 // Doc lines start with `///` or `//!`. If line starts with `//` and it's not doc, it's a normal comment line.
104 if trimmed.starts_with("//") && !trimmed.starts_with("///") && !trimmed.starts_with("//!") {
105 // Remove entire normal `//` comment line
106 continue;
107 }
108
109 // If we get here and the line starts with `///` or `//!`, it's a doc line and we keep it as is.
110
111 // Inline `//` in code lines:
112 // If there's `//` somewhere, and it's not at the start, we truncate at `//`.
113 // For doc lines (`///`, `//!`), we keep them intact, so only truncate if it's a code line.
114 if let Some(idx) = line.find("//") {
115 if trimmed.starts_with("///") || trimmed.starts_with("//!") {
116 // It's a doc line with `//` inside it (rare), keep entire line.
117 filtered.push(line);
118 } else {
119 // Code line with inline `//`, truncate at `//`.
120 let code_part = &line[..idx];
121 if !code_part.is_empty() {
122 filtered.push(code_part);
123 } else {
124 // Nothing left but whitespace, effectively a comment line => skip
125 continue;
126 }
127 }
128 } else {
129 // No `//` found, keep line as is
130 filtered.push(line);
131 }
132 }
133
134 filtered.join("\n")
135}
136