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.
27pub fn render_xml(
28    xml_type: &XmlOutputType,
29    content: &str,
30    context: &Option<XmlOutputContext>,
31) -> String {
32    match xml_type {
33        XmlOutputType::DevelopmentResult => development_result::render(content, context),
34        XmlOutputType::DevelopmentPlan => development_plan::render(content),
35        XmlOutputType::ReviewIssues => review_issues::render(content, context),
36        XmlOutputType::FixResult => fix_result::render(content, context),
37        XmlOutputType::CommitMessage => commit_message::render(content),
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    #[test]
46    fn test_render_xml_routes_to_development_result() {
47        let content = r#"<ralph-development-result>
48<ralph-status>completed</ralph-status>
49<ralph-summary>Done</ralph-summary>
50</ralph-development-result>"#;
51
52        let output = render_xml(&XmlOutputType::DevelopmentResult, content, &None);
53        assert!(
54            output.contains("✅"),
55            "Should route to development result renderer"
56        );
57    }
58
59    #[test]
60    fn test_render_xml_routes_to_review_issues() {
61        let content = r#"<ralph-issues>
62<ralph-issue>Test issue</ralph-issue>
63</ralph-issues>"#;
64
65        let output = render_xml(&XmlOutputType::ReviewIssues, content, &None);
66        assert!(
67            output.contains("1 issue"),
68            "Should route to issues renderer"
69        );
70    }
71
72    #[test]
73    fn test_render_xml_routes_to_commit_message() {
74        let content = r#"<ralph-commit>
75<ralph-subject>feat: add feature</ralph-subject>
76</ralph-commit>"#;
77
78        let output = render_xml(&XmlOutputType::CommitMessage, content, &None);
79        assert!(
80            output.contains("feat: add feature"),
81            "Should route to commit renderer"
82        );
83    }
84}