#![allow(dead_code)]
use serde_json::Value;
pub fn violation(json: &Value, code: i32) -> Option<String> {
if !(0..=4).contains(&code) {
return Some(format!("exit {code} is not one of proc's codes, 0 to 4"));
}
if !json["action"].is_string() {
return Some("no `action`".to_string());
}
if json["success"] != (code == 0) {
return Some(format!("exit {code} but success = {}", json["success"]));
}
if json.get("error").is_some() && json.get("exit_code").is_none() {
return Some("an `error` without `exit_code`".to_string());
}
if json.get("exit_code").is_some_and(|field| *field != code) {
return Some(format!("exit {code} but exit_code = {}", json["exit_code"]));
}
if json.get("reason").is_some() != (code == 4) {
return Some(format!(
"exit {code} with reason = {}: a reason comes with exit 4 only",
json["reason"]
));
}
None
}
pub fn check(json: &Value, code: i32, args: &[&str]) {
if let Some(wrong) = violation(json, code) {
panic!("proc {args:?} broke the JSON contract: {wrong}\n{json:#}");
}
}