1use crate::loop_runner::LoopReport;
2use crate::observe::Observation;
3use crate::orient::TargetCandidate;
4use crate::repo_chat::RepoChatAnswer;
5use serde::Serialize;
6
7#[derive(Serialize)]
8struct CandidateView<'a> {
9 stable_key: &'a str,
10 urgency: f64,
11 rationale: &'a str,
12 check_hints: &'a [String],
13}
14
15pub fn render_observation_report(observation: &Observation, json: bool) -> String {
17 render(observation, json)
18}
19
20pub fn render_candidate_report(candidates: &[TargetCandidate], json: bool) -> String {
22 let view = candidates
23 .iter()
24 .map(|candidate| CandidateView {
25 stable_key: &candidate.stable_key,
26 urgency: candidate.urgency,
27 rationale: &candidate.rationale,
28 check_hints: &candidate.check_hints,
29 })
30 .collect::<Vec<_>>();
31 render(&view, json)
32}
33
34pub fn render_loop_report(report: &LoopReport, json: bool) -> String {
36 render(report, json)
37}
38
39pub fn render_repo_chat_answer(answer: &RepoChatAnswer, json: bool) -> String {
41 render(answer, json)
42}
43
44fn render<T: Serialize + ?Sized>(value: &T, json: bool) -> String {
45 if json {
46 serde_json::to_string_pretty(value).unwrap_or_else(|_| "{}".into())
47 } else {
48 serde_json::to_string_pretty(value).unwrap_or_else(|_| "{}".into())
49 }
50}