Skip to main content

ralph_workflow/rendering/xml/
mod.rs

1//! Semantic XML renderers for user-friendly output.
2//!
3//! This module routes XML rendering to type-specific modules.
4//! Each XML output type (`DevelopmentResult`, `DevelopmentPlan`, etc.) has
5//! a dedicated renderer that transforms raw XML into user-friendly
6//! terminal output.
7//!
8//! # Graceful Degradation
9//!
10//! If XML parsing fails, renderers fall back to displaying the raw XML
11//! with a warning message. This ensures users always see output even if
12//! the format is unexpected.
13
14mod commit_message;
15mod development_plan;
16mod development_result;
17mod fix_result;
18mod helpers;
19mod review_issues;
20
21use crate::reducer::ui_event::{XmlOutputContext, XmlOutputType};
22
23/// Render XML content based on its type.
24///
25/// Returns formatted string for terminal display.
26/// Falls back to raw XML with warning if parsing fails.
27#[must_use]
28pub fn render_xml(
29    xml_type: &XmlOutputType,
30    content: &str,
31    output_context: &Option<XmlOutputContext>,
32) -> String {
33    match xml_type {
34        XmlOutputType::DevelopmentResult => {
35            development_result::render(content, output_context.as_ref())
36        }
37        XmlOutputType::DevelopmentPlan => development_plan::render(content),
38        XmlOutputType::ReviewIssues => review_issues::render(content, output_context.as_ref()),
39        XmlOutputType::FixResult => fix_result::render(content, output_context.as_ref()),
40        XmlOutputType::CommitMessage => commit_message::render(content),
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[test]
49    fn test_render_xml_routes_to_development_result() {
50        let content = r"<ralph-development-result>
51<ralph-status>completed</ralph-status>
52<ralph-summary>Done</ralph-summary>
53</ralph-development-result>";
54
55        let output = render_xml(&XmlOutputType::DevelopmentResult, content, &None);
56        assert!(
57            output.contains("✅"),
58            "Should route to development result renderer"
59        );
60    }
61
62    #[test]
63    fn test_render_xml_routes_to_review_issues() {
64        let content = r"<ralph-issues>
65<ralph-issue>Test issue</ralph-issue>
66</ralph-issues>";
67
68        let output = render_xml(&XmlOutputType::ReviewIssues, content, &None);
69        assert!(
70            output.contains("1 issue"),
71            "Should route to issues renderer"
72        );
73    }
74
75    #[test]
76    fn test_render_xml_routes_to_commit_message() {
77        let content = r"<ralph-commit>
78<ralph-subject>feat: add feature</ralph-subject>
79</ralph-commit>";
80
81        let output = render_xml(&XmlOutputType::CommitMessage, content, &None);
82        assert!(
83            output.contains("feat: add feature"),
84            "Should route to commit renderer"
85        );
86    }
87}