use std::path::Path;
use anyhow::Context;
use crate::model::{RustMir2Error, TargetMirDump};
use crate::render::sort_target_dumps;
fn sanitize_fragment_part(part: &str) -> String {
let mut out = String::with_capacity(part.len());
let mut previous_was_underscore = false;
for ch in part.chars() {
let keep = ch.is_ascii_alphanumeric() || ch == '-' || ch == '_';
if keep {
out.push(ch);
previous_was_underscore = false;
} else if !previous_was_underscore {
out.push('_');
previous_was_underscore = true;
}
}
let trimmed = out.trim_matches('_');
if trimmed.is_empty() {
"unknown".to_string()
} else {
trimmed.to_string()
}
}
pub fn fragment_file_name(fragment: &TargetMirDump) -> String {
let package_name = sanitize_fragment_part(&fragment.package_name);
let target_identity = sanitize_fragment_part(&fragment.target_identity);
format!("{package_name}__{target_identity}__mir.json")
}
pub fn write_fragment_to_dir(
output_dir: &Path,
fragment: &TargetMirDump,
) -> Result<(), RustMir2Error> {
std::fs::create_dir_all(output_dir)
.with_context(|| format!("failed to create output dir `{}`", output_dir.display()))?;
let path = output_dir.join(fragment_file_name(fragment));
let rendered = serde_json::to_string_pretty(fragment)?;
std::fs::write(&path, rendered)
.with_context(|| format!("failed to write fragment `{}`", path.display()))?;
Ok(())
}
pub fn load_fragments_from_dir(dir: &Path) -> Result<Vec<TargetMirDump>, RustMir2Error> {
let mut fragments = Vec::new();
for entry in std::fs::read_dir(dir)
.with_context(|| format!("failed to read fragment directory `{}`", dir.display()))?
{
let entry = entry?;
let path = entry.path();
if path.extension().and_then(|value| value.to_str()) != Some("json") {
continue;
}
let content = std::fs::read_to_string(&path)
.with_context(|| format!("failed to read fragment `{}`", path.display()))?;
let fragment = serde_json::from_str::<TargetMirDump>(&content)
.with_context(|| format!("failed to parse fragment `{}`", path.display()))?;
fragments.push(fragment);
}
sort_target_dumps(&mut fragments);
Ok(fragments)
}