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