use caexfer::{PreviewReport, Result, preview};
use super::args::Args;
use super::common::{conversion_options, emit, path_json};
use super::convert::omissions_json;
use super::json::{array, object, quote};
pub(super) fn run_preview(args: &Args) -> Result<u8> {
let report = preview(&args.paths[0], &args.paths[1], &conversion_options(args)?)?;
present_preview(args, &report)?;
Ok(0)
}
#[allow(clippy::too_many_lines)] fn present_preview(args: &Args, report: &PreviewReport) -> Result<()> {
if args.json {
let mut fields = vec![
("schema_version", "1".into()),
("operation", quote("conversion-preview")),
("scope", quote("input-to-output-route")),
("input", path_json(&args.paths[0])),
("output", path_json(&args.paths[1])),
("source_format", quote(report.source_format.name())),
("target_format", quote(report.target_format.name())),
("source_bytes", report.source_bytes.to_string()),
("points", report.points.to_string()),
("cells", report.cells.to_string()),
("fields", report.fields.to_string()),
("complete", report.complete.to_string()),
(
"notice_scope",
quote(if report.complete {
"source-and-destination"
} else {
"source-only"
}),
),
("omissions", omissions_json(&report.omissions)),
(
"limit",
report
.limit
.as_ref()
.map_or_else(|| "null".into(), |s| quote(s)),
),
];
if let Some(grid) = &report.voxel_estimate {
fields.push((
"voxel_grid",
object([
(
"origin",
array(grid.origin.into_iter().map(|n| n.to_string())),
),
("spacing", grid.spacing.to_string()),
(
"dimensions",
array(grid.dims.into_iter().map(|n| n.to_string())),
),
("cells", grid.cells.to_string()),
("max_triangle_checks", grid.triangle_checks.to_string()),
]),
));
}
if let Some(companion) = &report.mesh_output {
fields.push((
"mesh_output",
object([
(
"path",
args.mesh_out
.as_ref()
.map_or_else(|| "null".into(), |p| path_json(p)),
),
("omissions", omissions_json(&companion.omissions)),
]),
));
}
emit(&object(fields))?;
} else {
emit(&format!(
"Conversion preview {} → {}: {} → {}; source has {} bytes, {} points, {} cells, {} fields.",
args.paths[0].display(),
args.paths[1].display(),
report.source_format.name(),
report.target_format.name(),
report.source_bytes,
report.points,
report.cells,
report.fields
))?;
if let Some(grid) = &report.voxel_estimate {
emit(&format!(
"Grid: {} × {} × {} = {} cells; origin [{}, {}, {}], spacing {}; up to {} triangle checks.",
grid.dims[0],
grid.dims[1],
grid.dims[2],
grid.cells,
grid.origin[0],
grid.origin[1],
grid.origin[2],
grid.spacing,
grid.triangle_checks
))?;
}
if let Some(limit) = &report.limit {
emit(&format!("Limit: {limit}"))?;
}
for omission in &report.omissions {
emit(&format!("Notice: {}", omission.detail))?;
}
if let Some(companion) = &report.mesh_output {
for omission in &companion.omissions {
emit(&format!("Companion notice: {}", omission.detail))?;
}
}
if report.complete {
emit("Destination writer checked; notices cover source and destination.")?;
} else {
emit(
"Grid work estimate only; sampling and destination checks remain for conversion.",
)?;
}
emit("No output written.")?;
}
Ok(())
}