use crate::list_envelope::{ListEnvelope, Reason, Total, Unit};
use serde_json::{Map, Value};
pub const COMMAND: &str = "inspect";
pub const UNIT: Unit = Unit::Items;
pub const NARROW: &[&str] = &["topK", "scope", "sections"];
pub const LIST_ENVELOPE_SUFFIX: &str = "_list_envelope";
pub fn derive_inspect_wire_key(list_key: &str) -> String {
format!("{list_key}{LIST_ENVELOPE_SUFFIX}")
}
pub fn build_inspect_envelope(shown: usize, total: usize) -> Option<ListEnvelope> {
if shown >= total {
return None;
}
Some(ListEnvelope::new(
shown,
Total::Exact(total),
UNIT,
vec![Reason::Cap],
NARROW,
))
}
pub fn attach_inspect_envelope(
details: &mut Map<String, Value>,
list_key: &str,
shown: usize,
total: usize,
) -> Option<ListEnvelope> {
let envelope = build_inspect_envelope(shown, total)?;
if let Ok(val) = serde_json::to_value(&envelope) {
details.insert(derive_inspect_wire_key(list_key), val);
}
Some(envelope)
}
pub fn render_inspect_envelope_trailer(envelope: &ListEnvelope, list_key: &str) -> Option<String> {
let wire_key = derive_inspect_wire_key(list_key);
let data = serde_json::json!({ wire_key: envelope });
let text = crate::ndjson_text::build_ndjson_text(
"",
&data,
Some(&format!("payload.details.{list_key}")),
false,
);
if text.is_empty() {
None
} else {
Some(text)
}
}
pub fn trailer_for_envelope(envelope_val: Option<&Value>, list_key: &str) -> Option<String> {
let val = envelope_val?;
let envelope: ListEnvelope = serde_json::from_value(val.clone()).ok()?;
render_inspect_envelope_trailer(&envelope, list_key)
}
pub fn trailer_from_details(details: &Map<String, Value>, list_key: &str) -> Option<String> {
let wire_key = derive_inspect_wire_key(list_key);
trailer_for_envelope(details.get(&wire_key), list_key)
}