use std::path::{Path, PathBuf};
use serde_json::Value;
use super::check_finite_classifier::{
classify_error_json, classify_layer_coverage, CheckFiniteCoverageOutcome,
CheckFiniteErrorOutcome, F11_REQUIRED_OP_PREFIXES,
};
use crate::error::{CliError, Result};
pub(crate) fn run(
error_file: Option<&Path>,
list_file: Option<&Path>,
min_layers: usize,
json: bool,
) -> Result<()> {
if error_file.is_none() && list_file.is_none() {
return Err(CliError::ValidationFailed(
"apr check-finite-lint: at least one of --error-file or --list-file is required"
.to_string(),
));
}
let err_outcome = match error_file {
Some(p) => {
if !p.exists() {
return Err(CliError::FileNotFound(PathBuf::from(p)));
}
let body_text = std::fs::read_to_string(p)?;
let body: Value = serde_json::from_str(&body_text).map_err(|e| {
CliError::InvalidFormat(format!(
"apr check-finite-lint: failed to parse error JSON from {}: {e}",
p.display()
))
})?;
Some(classify_error_json(&body))
}
None => None,
};
let cov_outcome = match list_file {
Some(p) => {
if !p.exists() {
return Err(CliError::FileNotFound(PathBuf::from(p)));
}
let body_text = std::fs::read_to_string(p)?;
let body: Value = serde_json::from_str(&body_text).map_err(|e| {
CliError::InvalidFormat(format!(
"apr check-finite-lint: failed to parse list JSON from {}: {e}",
p.display()
))
})?;
Some(classify_layer_coverage(
&body,
min_layers,
F11_REQUIRED_OP_PREFIXES,
))
}
None => None,
};
print_report(
error_file,
list_file,
err_outcome.as_ref(),
cov_outcome.as_ref(),
json,
);
if let Some(o) = &err_outcome {
if !matches!(o, CheckFiniteErrorOutcome::Ok) {
return Err(CliError::ValidationFailed(format!(
"check-finite-lint error-json gate rejected body: {o:?}"
)));
}
}
if let Some(o) = &cov_outcome {
if !matches!(o, CheckFiniteCoverageOutcome::Ok { .. }) {
return Err(CliError::ValidationFailed(format!(
"check-finite-lint layer-coverage gate rejected body: {o:?}"
)));
}
}
Ok(())
}
fn print_report(
error_file: Option<&Path>,
list_file: Option<&Path>,
err: Option<&CheckFiniteErrorOutcome>,
cov: Option<&CheckFiniteCoverageOutcome>,
json: bool,
) {
if json {
let obj = serde_json::json!({
"error_file": error_file.map(|p| p.display().to_string()),
"list_file": list_file.map(|p| p.display().to_string()),
"error_json": err.map(|o| format!("{o:?}")),
"layer_coverage": cov.map(|o| format!("{o:?}")),
});
println!("{}", serde_json::to_string_pretty(&obj).unwrap_or_default());
return;
}
println!("check-finite-lint report");
if let Some(p) = error_file {
println!(" error_file : {}", p.display());
}
if let Some(p) = list_file {
println!(" list_file : {}", p.display());
}
if let Some(o) = err {
println!(" error_json : {o:?}");
}
if let Some(o) = cov {
println!(" layer_coverage: {o:?}");
}
}