use crate::list_envelope::{derive_wire_key, ListEnvelope, Reason, Total, Unit};
use crate::list_surfaces::ReasonKind;
pub const LIST_ID: &str = "bash.output";
pub const WIRE_KEY: &str = "bash_output_list_envelope";
pub const UNIT: Unit = Unit::Lines;
pub const REASON: Reason = Reason::Cap;
pub const REASON_KIND: ReasonKind = ReasonKind::Selecting;
pub const NARROW: &[&str] = &[];
#[inline]
pub fn count_output_lines(output: &str) -> usize {
output.lines().count()
}
#[inline]
pub fn wire_key() -> String {
derive_wire_key(LIST_ID, true)
}
pub fn build_bash_output_envelope(shown: usize, total_input_lines: usize) -> Option<ListEnvelope> {
if shown >= total_input_lines {
None
} else {
Some(ListEnvelope::new(
shown,
Total::Exact(total_input_lines),
UNIT,
vec![REASON],
NARROW,
))
}
}
pub fn build_envelope_from_output(
agent_received_output: &str,
input_line_count: usize,
) -> Option<ListEnvelope> {
let shown = count_output_lines(agent_received_output);
build_bash_output_envelope(shown, input_line_count)
}
pub fn append_envelope_trailer(
agent_received_output: &mut String,
input_line_count: usize,
) -> Option<ListEnvelope> {
let body_lines = count_output_lines(agent_received_output);
if body_lines >= input_line_count {
return None;
}
let envelope = ListEnvelope::new(
body_lines.saturating_add(1),
Total::Exact(input_line_count),
UNIT,
vec![REASON],
NARROW,
);
let trailer = envelope_trailer(&envelope);
if !agent_received_output.is_empty() && !agent_received_output.ends_with('\n') {
agent_received_output.push('\n');
}
agent_received_output.push_str(&trailer);
Some(envelope)
}
pub fn envelope_trailer(envelope: &ListEnvelope) -> String {
let mut data = serde_json::Map::new();
data.insert(
derive_wire_key(LIST_ID, false),
serde_json::to_value(envelope).expect("ListEnvelope serialization"),
);
crate::ndjson_text::build_ndjson_text(
"",
&serde_json::Value::Object(data),
Some(LIST_ID),
false,
)
}
pub fn attach_bash_output_envelope(
data: &mut serde_json::Map<String, serde_json::Value>,
envelope: &Option<ListEnvelope>,
) {
if let Some(env) = envelope {
data.insert(
WIRE_KEY.to_string(),
serde_json::to_value(env).expect("ListEnvelope serialization"),
);
}
}
pub fn produce_bash_reply_data(
output: String,
envelope: Option<ListEnvelope>,
) -> serde_json::Map<String, serde_json::Value> {
let mut map = serde_json::Map::new();
map.insert("output".to_string(), serde_json::Value::String(output));
attach_bash_output_envelope(&mut map, &envelope);
map
}