Skip to main content

camel_processor/data_format/
xml.rs

1use camel_api::body::Body;
2use camel_api::body_converter::{BodyType, convert};
3use camel_api::data_format::DataFormat;
4use camel_api::error::CamelError;
5
6pub struct XmlDataFormat;
7
8impl DataFormat for XmlDataFormat {
9    fn name(&self) -> &str {
10        "xml"
11    }
12
13    fn marshal(&self, body: Body) -> Result<Body, CamelError> {
14        match body {
15            Body::Xml(_) => convert(body, BodyType::Text),
16            Body::Text(_) => Ok(body),
17            Body::Stream(_) => Err(CamelError::TypeConversionFailed(
18                "cannot marshal Body::Stream — add 'stream_cache' or 'convert_body_to' before this step".to_string(),
19            )),
20            Body::Empty | Body::Bytes(_) | Body::Json(_) => Err(CamelError::TypeConversionFailed(
21                "XmlDataFormat::marshal only supports Body::Xml and Body::Text".to_string(),
22            )),
23        }
24    }
25
26    fn unmarshal(&self, body: Body) -> Result<Body, CamelError> {
27        match body {
28            Body::Xml(_) => Ok(body),
29            Body::Text(_) | Body::Bytes(_) => convert(body, BodyType::Xml),
30            Body::Stream(_) => Err(CamelError::TypeConversionFailed(
31                "cannot unmarshal Body::Stream directly — use UnmarshalService which auto-materializes"
32                    .to_string(),
33            )),
34            Body::Empty | Body::Json(_) => Err(CamelError::TypeConversionFailed(
35                "XmlDataFormat::unmarshal only supports Body::Xml, Body::Text, and Body::Bytes"
36                    .to_string(),
37            )),
38        }
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45    use bytes::Bytes;
46
47    #[test]
48    fn test_name() {
49        assert_eq!(XmlDataFormat.name(), "xml");
50    }
51
52    #[test]
53    fn test_unmarshal_text_to_xml() {
54        let body = Body::Text("<root><child>value</child></root>".to_string());
55        let result = XmlDataFormat.unmarshal(body).unwrap();
56        assert!(matches!(result, Body::Xml(_)));
57    }
58
59    #[test]
60    fn test_unmarshal_bytes_to_xml() {
61        let body = Body::Bytes(Bytes::from_static(b"<root/>"));
62        let result = XmlDataFormat.unmarshal(body).unwrap();
63        assert!(matches!(result, Body::Xml(_)));
64    }
65
66    #[test]
67    fn test_unmarshal_invalid_xml() {
68        let body = Body::Text("not xml".to_string());
69        let result = XmlDataFormat.unmarshal(body);
70        assert!(matches!(result, Err(CamelError::TypeConversionFailed(_))));
71    }
72
73    #[test]
74    fn test_unmarshal_xml_noop() {
75        let body = Body::Xml("<root/>".to_string());
76        let result = XmlDataFormat.unmarshal(body).unwrap();
77        assert!(matches!(result, Body::Xml(_)));
78    }
79
80    #[test]
81    fn test_unmarshal_unsupported_variant() {
82        let body = Body::Empty;
83        let result = XmlDataFormat.unmarshal(body);
84        assert!(matches!(result, Err(CamelError::TypeConversionFailed(_))));
85    }
86
87    #[test]
88    fn test_marshal_xml_to_text() {
89        let body = Body::Xml("<root>content</root>".to_string());
90        let result = XmlDataFormat.marshal(body).unwrap();
91        assert_eq!(result, Body::Text("<root>content</root>".to_string()));
92    }
93
94    #[test]
95    fn test_marshal_text_noop() {
96        let body = Body::Text("already text".to_string());
97        let result = XmlDataFormat.marshal(body).unwrap();
98        assert_eq!(result, Body::Text("already text".to_string()));
99    }
100
101    #[test]
102    fn test_marshal_unsupported_variant() {
103        let body = Body::Empty;
104        let result = XmlDataFormat.marshal(body);
105        assert!(matches!(result, Err(CamelError::TypeConversionFailed(_))));
106    }
107}