use super::pretty_print;
pub(in crate::print) fn try_parse_and_format_module(wrapped: &str) -> Option<String> {
let raw = try_parse_and_format_module_raw(wrapped)?;
let lines: Vec<&str> = raw.split('\n').collect();
let mut collapsed: Vec<&str> = Vec::new();
let mut prev_blank = false;
for line in &lines {
if line.is_empty() {
if prev_blank {
continue;
}
prev_blank = true;
} else {
prev_blank = false;
}
collapsed.push(line);
}
let mut attached: Vec<&str> = Vec::with_capacity(collapsed.len());
let mut i = 0;
while i < collapsed.len() {
attached.push(collapsed[i]);
let trim = collapsed[i].trim_start();
let ends_doc_comment = trim.trim_end() == "-}";
let next_is_import =
i + 2 < collapsed.len() && collapsed[i + 2].trim_start().starts_with("import ");
if (trim.starts_with("--") || ends_doc_comment)
&& i + 2 < collapsed.len()
&& collapsed[i + 1].is_empty()
&& !collapsed[i + 2].is_empty()
&& !collapsed[i + 2].trim_start().starts_with("--")
&& !next_is_import
{
i += 2;
} else if trim.starts_with("--")
&& next_is_import
&& i + 2 < collapsed.len()
&& collapsed[i + 1].is_empty()
{
attached.push("");
i += 1;
} else {
i += 1;
}
}
let collapsed = attached;
let mut loosened: Vec<String> = Vec::with_capacity(collapsed.len() + 4);
let mut j = 0;
while j < collapsed.len() {
loosened.push(collapsed[j].to_string());
if collapsed[j].trim_start().starts_with("import ")
&& j + 2 < collapsed.len()
&& collapsed[j + 1].is_empty()
&& !collapsed[j + 2].is_empty()
&& collapsed[j + 2].trim_start().starts_with("--")
{
let mut k = j + 1;
while k < collapsed.len()
&& !collapsed[k].trim_start().starts_with("import ")
&& !collapsed[k].is_empty()
{
k += 1;
}
let _ = k;
loosened.push(String::new());
}
j += 1;
}
let collapsed_strings = loosened;
let collapsed: Vec<&str> = collapsed_strings.iter().map(|s| s.as_str()).collect();
let mut output = String::new();
for (idx, line) in collapsed.iter().enumerate() {
if idx > 0 {
output.push('\n');
}
if line.is_empty() {
} else {
output.push_str(" ");
output.push_str(line);
}
}
Some(output)
}
pub(in crate::print) fn try_parse_and_format_full_module(raw: &str) -> Option<String> {
let owned = raw.to_string();
let result = std::panic::catch_unwind(|| {
let module = crate::parse::parse(&owned).ok()?;
let first = pretty_print(&module);
let module2 = crate::parse::parse(&first).ok()?;
let second = pretty_print(&module2);
if first == second { Some(first) } else { None }
});
let formatted = match result {
Ok(Some(f)) => f,
_ => return None,
};
Some(formatted.trim_end_matches('\n').to_string())
}
pub(in crate::print) fn try_parse_and_format_module_raw(wrapped: &str) -> Option<String> {
let wrapped_owned = wrapped.to_string();
let result = std::panic::catch_unwind(|| {
let module = crate::parse::parse(&wrapped_owned).ok()?;
let first = pretty_print(&module);
let module2 = crate::parse::parse(&first).ok()?;
let second = pretty_print(&module2);
if first == second { Some(first) } else { None }
});
let formatted = match result {
Ok(Some(f)) => f,
_ => return None,
};
let header_end = formatted.find('\n')? + 1;
let rest = &formatted[header_end..];
let trimmed = rest.trim_start_matches('\n');
if trimmed.is_empty() {
return None;
}
let decl_text = trimmed.trim_end_matches('\n');
if decl_text.is_empty() {
return None;
}
Some(decl_text.to_string())
}
pub(in crate::print) fn try_parse_and_format_expr(wrapped: &str) -> Option<String> {
let wrapped_owned = wrapped.to_string();
let result = std::panic::catch_unwind(|| {
let module = crate::parse::parse(&wrapped_owned).ok()?;
let first = pretty_print(&module);
let module2 = crate::parse::parse(&first).ok()?;
let second = pretty_print(&module2);
if first == second { Some(first) } else { None }
});
let formatted = match result {
Ok(Some(f)) => f,
_ => return None,
};
let marker = "docTemp__ =\n";
let idx = formatted.find(marker)?;
let body = &formatted[idx + marker.len()..];
let body = body.trim_end_matches('\n');
if body.is_empty() {
return None;
}
let mut result_lines: Vec<String> = Vec::new();
for line in body.split('\n') {
if line.is_empty() {
result_lines.push(String::new());
} else if let Some(stripped) = line.strip_prefix(" ") {
result_lines.push(stripped.to_string());
} else {
return None;
}
}
Some(result_lines.join("\n"))
}