use std::collections::BTreeMap;
use std::fmt::Write as _;
use std::path::{Path, PathBuf};
use crate::model::{PackageMirDump, RustMir2Error, TargetMirDump, WorkspaceMirDump};
pub fn render_workspace_mir_json(
dump: &WorkspaceMirDump,
pretty: bool,
) -> Result<String, RustMir2Error> {
let mut sorted = dump.clone();
sort_workspace_dump(&mut sorted);
let rendered = if pretty {
serde_json::to_string_pretty(&sorted)
} else {
serde_json::to_string(&sorted)
}?;
Ok(rendered)
}
pub fn default_output_path_for_cwd(cwd: &Path) -> PathBuf {
cwd.join("rust_mir2.json")
}
pub fn default_mir_output_dir_for_cwd(cwd: &Path) -> PathBuf {
cwd.join("rust_mir2_emit_mir")
}
pub(crate) fn sort_target_dumps(targets: &mut [TargetMirDump]) {
targets.sort_by(|left, right| {
(
&left.package_name,
&left.target_identity,
&left.target_kind,
&left.target_name,
&left.target_src_path,
)
.cmp(&(
&right.package_name,
&right.target_identity,
&right.target_kind,
&right.target_name,
&right.target_src_path,
))
});
}
fn sort_packages(packages: &mut [PackageMirDump]) {
packages.sort_by(|left, right| left.package_name.cmp(&right.package_name));
for package in packages {
sort_target_dumps(&mut package.targets);
}
}
fn sort_workspace_dump(dump: &mut WorkspaceMirDump) {
sort_packages(&mut dump.packages);
}
pub(crate) fn build_packages_from_targets(targets: Vec<TargetMirDump>) -> Vec<PackageMirDump> {
let mut grouped = BTreeMap::<String, Vec<TargetMirDump>>::new();
for target in targets {
grouped
.entry(target.package_name.clone())
.or_default()
.push(target);
}
let mut packages = grouped
.into_iter()
.map(|(package_name, mut targets)| {
sort_target_dumps(&mut targets);
let merged_mir_raw = merge_target_mir(&targets);
PackageMirDump {
package_name,
targets,
merged_mir_raw,
}
})
.collect::<Vec<_>>();
sort_packages(&mut packages);
packages
}
fn merge_target_mir(targets: &[TargetMirDump]) -> String {
let mut out = String::new();
for target in targets {
let content = target.mir_raw.trim();
if content.is_empty() {
continue;
}
if !out.is_empty() {
out.push_str("\n\n");
}
let _ = writeln!(&mut out, "=== TARGET {} / mir ===", target.target_identity);
let _ = writeln!(&mut out, "package_name: {}", target.package_name);
let _ = writeln!(&mut out, "crate_name: {}", target.crate_name);
let _ = writeln!(&mut out, "target_name: {}", target.target_name);
let _ = writeln!(&mut out, "target_kind: {}", target.target_kind);
let _ = writeln!(&mut out, "target_profile: {}", target.target_profile);
let _ = writeln!(
&mut out,
"target_src_path: {}",
target.target_src_path.display()
);
let _ = writeln!(&mut out);
out.push_str(content);
}
out
}