ralph_workflow/rendering/xml/
mod.rs1mod commit_message;
15mod development_plan;
16mod development_result;
17mod fix_result;
18mod helpers;
19mod review_issues;
20
21use crate::files::llm_output_extraction::SkillsMcp;
22use crate::reducer::ui_event::{XmlOutputContext, XmlOutputType};
23
24pub fn render_skills_mcp_markdown(output: &mut String, skills_mcp: Option<&SkillsMcp>) {
28 use std::fmt::Write as _;
29
30 if let Some(sm) = skills_mcp {
31 let has_structured = !sm.skills.is_empty() || !sm.mcps.is_empty();
32 if has_structured || sm.raw_content.is_some() {
33 output.push_str(" - Skills & MCP:\n");
34 for skill in &sm.skills {
35 if let Some(ref reason) = skill.reason {
36 writeln!(output, " - skill: {} \u{2014} {}", skill.name, reason).unwrap();
37 } else {
38 writeln!(output, " - skill: {}", skill.name).unwrap();
39 }
40 }
41 for mcp in &sm.mcps {
42 if let Some(ref reason) = mcp.reason {
43 writeln!(output, " - mcp: {} \u{2014} {}", mcp.name, reason).unwrap();
44 } else {
45 writeln!(output, " - mcp: {}", mcp.name).unwrap();
46 }
47 }
48 if let Some(ref raw) = sm.raw_content {
49 let trimmed: &str = raw.trim();
50 if !trimmed.is_empty() && !has_structured {
51 writeln!(output, " - {trimmed}").unwrap();
52 }
53 }
54 }
55 }
56}
57
58#[must_use]
63pub fn render_xml(
64 xml_type: &XmlOutputType,
65 content: &str,
66 output_context: &Option<XmlOutputContext>,
67) -> String {
68 match xml_type {
69 XmlOutputType::DevelopmentResult => {
70 development_result::render(content, output_context.as_ref())
71 }
72 XmlOutputType::DevelopmentPlan => development_plan::render(content),
73 XmlOutputType::ReviewIssues => review_issues::render(content, output_context.as_ref()),
74 XmlOutputType::FixResult => fix_result::render(content, output_context.as_ref()),
75 XmlOutputType::CommitMessage => commit_message::render(content),
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn test_render_xml_routes_to_development_result() {
85 let content = r"<ralph-development-result>
86<ralph-status>completed</ralph-status>
87<ralph-summary>Done</ralph-summary>
88</ralph-development-result>";
89
90 let output = render_xml(&XmlOutputType::DevelopmentResult, content, &None);
91 assert!(
92 output.contains("✅"),
93 "Should route to development result renderer"
94 );
95 }
96
97 #[test]
98 fn test_render_xml_routes_to_review_issues() {
99 let content = r"<ralph-issues>
100<ralph-issue>Test issue</ralph-issue>
101</ralph-issues>";
102
103 let output = render_xml(&XmlOutputType::ReviewIssues, content, &None);
104 assert!(
105 output.contains("1 issue"),
106 "Should route to issues renderer"
107 );
108 }
109
110 #[test]
111 fn test_render_xml_routes_to_commit_message() {
112 let content = r"<ralph-commit>
113<ralph-subject>feat: add feature</ralph-subject>
114</ralph-commit>";
115
116 let output = render_xml(&XmlOutputType::CommitMessage, content, &None);
117 assert!(
118 output.contains("feat: add feature"),
119 "Should route to commit renderer"
120 );
121 }
122}