1pub fn normalize_doc_string(s: &str) -> Option<String> {
5 let trimmed = s.trim();
6 if trimmed.is_empty() {
7 None
8 } else {
9 Some(
10 remove_asterisks_if_asterisk_docs(&normalize_indentation(s))
11 .trim()
12 .to_string(),
13 )
14 }
15}
16
17pub fn normalize_indentation(string: &str) -> String {
19 let lines = string.lines();
20 if lines.count() == 1 {
21 string.trim().to_string()
22 } else {
23 let num_leading = string
24 .lines()
25 .filter_map(|l| l.chars().position(|c| !c.is_whitespace()))
26 .min()
27 .unwrap_or(0);
28 string
29 .lines()
30 .map(|line| {
31 if line.len() > num_leading {
32 &line[num_leading..]
33 } else {
34 line
35 }
36 })
37 .map(|l| l.trim_end())
38 .collect::<Vec<_>>()
39 .join("\n")
40 }
41}
42
43pub fn remove_asterisks_if_asterisk_docs(s: &str) -> String {
45 let should_remove_asterisks = s
46 .lines()
47 .all(|l| l.is_empty() || l.starts_with("* ") || l == "*");
48 if should_remove_asterisks {
49 s.lines()
50 .map(|line| {
51 if let Some(fmt) = line.strip_prefix("* ") {
52 fmt
53 } else if line == "*" {
54 ""
55 } else {
56 line
57 }
58 })
59 .collect::<Vec<_>>()
60 .join("\n")
61 } else {
62 s.to_string()
63 }
64}