use quick_xml::{events::Event, name::ResolveResult}; use raxb::{ de::{XmlDeserialize, XmlDeserializeError}, ty::S, XmlDeserialize, }; #[derive(Default, Debug, XmlDeserialize, PartialEq, Eq)] #[raxb(root = b"a")] pub struct A { #[raxb(name = b"d", ty = "child", default)] pub d: String, } #[derive(Default, Debug, XmlDeserialize, PartialEq, Eq)] #[raxb(root = b"b")] pub struct B { #[raxb(name = b"d", ty = "child", default)] pub d: String, } #[derive(Debug, PartialEq, Eq)] enum E { A(A), B(B), } impl XmlDeserialize for E { fn is_enum() -> bool { true } fn root() -> Option { None } fn target_ns() -> Option { None } fn xml_deserialize( reader: &mut quick_xml::NsReader, _target_ns: raxb::ty::XmlTag, _tag: raxb::ty::XmlTargetNs, _attributes: quick_xml::events::attributes::Attributes, _is_empty: bool, ) -> raxb::de::XmlDeserializeResult where Self: Sized, R: std::io::prelude::BufRead, { let mut result = Option::::None; let mut buf = Vec::::new(); loop { match reader.read_resolved_event_into(&mut buf)? { (ResolveResult::Unbound, Event::Start(e)) => match e.local_name().as_ref() { root if Some(root) == A::root() => { result = Some(E::A(A::xml_deserialize( reader, &[], b"a", e.attributes(), false, )?)); break; } root if Some(root) == B::root() => { result = Some(E::B(B::xml_deserialize( reader, &[], b"b", e.attributes(), false, )?)); break; } _ => { return Err(raxb::de::XmlDeserializeError::UnknownVariant( String::from_utf8_lossy(e.name().as_ref()).to_string(), S(b"'a' | 'b'"), )); } }, (ResolveResult::Unbound, Event::Empty(e)) => match e.local_name().as_ref() { root if Some(root) == A::root() => { result = Some(E::A(A::xml_deserialize( reader, &[], b"a", e.attributes(), true, )?)); break; } root if Some(root) == B::root() => { result = Some(E::B(B::xml_deserialize( reader, &[], b"b", e.attributes(), true, )?)); break; } _ => { return Err(raxb::de::XmlDeserializeError::UnknownVariant( String::from_utf8_lossy(e.name().as_ref()).to_string(), S(b"'a' | 'b'"), )); } }, (_, Event::Eof) => { break; } _ => {} } } result.ok_or(XmlDeserializeError::MissingVariant(S(b"a | b"))) } } #[test] fn test_enums_serde() -> anyhow::Result<()> { let test_xml1 = r#"A"#; let v1: E = raxb::de::from_str(test_xml1)?; assert_eq!(v1, E::A(A { d: "A".to_string() })); let test_xml2 = r#"B"#; let v2: E = raxb::de::from_str(test_xml2)?; assert_eq!(v2, E::B(B { d: "B".to_string() })); Ok(()) }