use serde_json::Value;
use crate::query::json::J;
const PARTIAL: &str = "partial";
const NOT_APPLIED: &str = "not-applied";
#[derive(Debug, Clone, PartialEq)]
pub struct AuditLane {
label: &'static str,
record: Option<Value>,
}
impl AuditLane {
#[cfg(test)]
pub const SYNTAX: AuditLane = AuditLane {
label: "syntax",
record: None,
};
pub fn read(graph: &Value) -> AuditLane {
let stats = graph.get("stats");
let record = stats.and_then(|s| s.get("lane")).cloned();
let state = record.as_ref().and_then(|r| r.get("state")?.as_str());
let label = if state == Some(PARTIAL) {
"enriched-partial"
} else if stats.and_then(|s| s.get("semantic")).is_some() {
"enriched"
} else {
"syntax"
};
AuditLane { label, record }
}
pub fn label(&self) -> &'static str {
self.label
}
pub fn header(&self) -> String {
let Some(record) = &self.record else {
return self.label.to_string();
};
let field = |key: &str| record.get(key).and_then(Value::as_str).map(one_line);
match (field("state").as_deref(), field("reason"), field("detail")) {
(Some(PARTIAL), _, Some(detail)) => format!("{} ({detail})", self.label),
(Some(NOT_APPLIED), Some(reason), Some(detail)) => {
format!(
"{} (enriched lane not applied: {reason}: {detail})",
self.label
)
}
(Some(NOT_APPLIED), Some(reason), None) => {
format!("{} (enriched lane not applied: {reason})", self.label)
}
_ => self.label.to_string(),
}
}
pub fn json_fields(&self) -> Vec<(&'static str, J)> {
let Some(record) = &self.record else {
return Vec::new();
};
let mut fields = vec![("lane_detail", raw(record))];
if let Some(compilations) = record.get("compilations") {
fields.push(("compilations", raw(compilations)));
}
fields
}
}
fn one_line(text: &str) -> String {
text.chars()
.map(|c| {
if c.is_control() {
c.escape_debug().to_string()
} else {
c.to_string()
}
})
.collect()
}
fn raw(value: &Value) -> J {
J::RawNum(value.to_string())
}