use crate::reply::step::{Doc, Step};
use super::parts::{line, line_over, listing, when};
use super::records::preview;
pub(super) fn step(step: &Step) -> String {
let parts = [
Some(doc("meta", &step.meta)),
Some(doc("request", &step.request)),
Some(doc("staging", &step.staging)),
when(
!step.response.is_empty(),
&step
.response
.iter()
.map(|body| doc("response", body))
.collect::<Vec<String>>()
.join("\n"),
),
when(
!step.tools.is_empty(),
&step
.tools
.iter()
.map(|call| {
line_over(
&line(vec![
Some(call.tool_id.clone()),
when(call.is_error, "ERROR"),
]),
Some(format!(
"{}\n{}",
doc("in", &call.input),
doc("out", &call.output)
)),
)
})
.collect::<Vec<String>>()
.join("\n"),
),
step.stderr.as_ref().map(|log| preview("stderr", log)),
step.driver.as_ref().map(|log| preview("driver", log)),
];
listing(
&format!("step {}", step.seq),
parts.into_iter().flatten().collect(),
"",
)
}
fn doc(name: &str, doc: &Doc) -> String {
match doc {
Doc::Json { raw } => line_over(name, Some(raw.clone())),
Doc::Absent => format!("{name}: not written"),
Doc::Unparsed { note, raw } => line_over(&format!("{name} ({note})"), Some(raw.clone())),
Doc::Unknown(word) => format!("{name}: {word} (this seat has no reading of that record)"),
}
}