use std::borrow::Cow; use xmlparser_derive::{XmlRead, XmlResult, XmlWrite}; #[derive(XmlWrite, XmlRead, PartialEq, Debug)] #[xml(tag = "tag1")] struct Tag1<'a> { #[xml(attr = "att1")] att1: Option>, #[xml(text)] content: Cow<'a, str>, } #[derive(XmlWrite, XmlRead, PartialEq, Debug)] #[xml(tag = "tag2")] #[xml(leaf)] struct Tag2<'a> { #[xml(attr = "att1")] att1: Cow<'a, str>, #[xml(attr = "att2")] att2: Cow<'a, str>, } #[derive(XmlWrite, XmlRead, PartialEq, Debug)] #[xml(tag = "tag3")] struct Tag3<'a> { #[xml(attr = "att1")] att1: Cow<'a, str>, #[xml(child = "tag1")] tag1: Vec>, #[xml(child = "tag2")] tag2: Option>, #[xml(flatten_text = "text")] text: Option>, } #[derive(XmlWrite, XmlRead, PartialEq, Debug)] enum Tag<'a> { #[xml(tag = "tag1")] Tag1(Tag1<'a>), #[xml(tag = "tag2")] Tag2(Tag2<'a>), #[xml(tag = "tag3")] Tag3(Tag3<'a>), } macro_rules! test_suite { ($func:ident, $type:tt, $string:tt, $struct:expr) => { #[test] fn $func() -> XmlResult<()> { let _ = env_logger::builder() .is_test(true) .format_timestamp(None) .try_init(); // test writing assert_eq!($string, ($struct).to_string()?); // test reading assert_eq!($struct, $type::from_str($string)?); Ok(()) } }; } test_suite!( tag3_1, Tag3, r#"contenttag3_content"#, Tag3 { att1: "att1".into(), tag1: vec![Tag1 { att1: None, content: "content".into(), }], tag2: None, text: Some("tag3_content".into()), } ); test_suite!( tag3_2, Tag3, r#"content1content2"#, Tag3 { att1: "att1".into(), tag1: vec![ Tag1 { att1: Some("att11".into()), content: "content1".into(), }, Tag1 { att1: Some("att12".into()), content: "content2".into(), }, ], tag2: None, text: None, } ); test_suite!( tag1, Tag, r#"content"#, Tag::Tag1(Tag1 { att1: Some("att1".into()), content: "content".into(), }) ); test_suite!( tag, Tag, r#""#, Tag::Tag2(Tag2 { att1: "att1".into(), att2: "att2".into(), }) );