From 4d627b514a3c7d2b33b8681ffcfc488943bf33e2 Mon Sep 17 00:00:00 2001 From: rsdy Date: Thu, 29 Sep 2022 17:12:08 +0100 Subject: [PATCH] Use field name as tag for `Vec` serialization --- instant-xml-macros/src/lib.rs | 2 +- instant-xml-macros/src/ser.rs | 2 +- instant-xml/src/impls.rs | 18 +++--------------- instant-xml/src/lib.rs | 3 +++ instant-xml/tests/entities.rs | 10 +++++----- 5 files changed, 13 insertions(+), 22 deletions(-) diff --git a/instant-xml-macros/src/lib.rs b/instant-xml-macros/src/lib.rs index 2d5721f..ae6ae88 100644 --- a/instant-xml-macros/src/lib.rs +++ b/instant-xml-macros/src/lib.rs @@ -820,7 +820,7 @@ mod tests { field_1: String, field_2: u8, } - }).to_string(), "impl ToXml for TestStruct { fn serialize < W : :: core :: fmt :: Write + ? :: core :: marker :: Sized > (& self , serializer : & mut instant_xml :: Serializer < W > ,) -> Result < () , instant_xml :: Error > { let prefix = serializer . write_start (\"TestStruct\" , \"\" , false) ? ; debug_assert_eq ! (prefix , None) ; let mut new = :: instant_xml :: ser :: Context :: < 0usize > :: default () ; new . default_ns = \"\" ; let old = serializer . push (new) ? ; serializer . end_start () ? ; match < String as ToXml > :: KIND { :: instant_xml :: Kind :: Element (_) => { self . field_1 . serialize (serializer) ? ; } :: instant_xml :: Kind :: Scalar => { let prefix = serializer . write_start (\"FIELD_1\" , \"\" , true) ? ; serializer . end_start () ? ; self . field_1 . serialize (serializer) ? ; serializer . write_close (prefix , \"FIELD_1\") ? ; } } match < u8 as ToXml > :: KIND { :: instant_xml :: Kind :: Element (_) => { self . field_2 . serialize (serializer) ? ; } :: instant_xml :: Kind :: Scalar => { let prefix = serializer . write_start (\"FIELD_2\" , \"\" , true) ? ; serializer . end_start () ? ; self . field_2 . serialize (serializer) ? ; serializer . write_close (prefix , \"FIELD_2\") ? ; } } serializer . write_close (prefix , \"TestStruct\") ? ; serializer . pop (old) ; Ok (()) } const KIND : :: instant_xml :: Kind = :: instant_xml :: Kind :: Element (:: instant_xml :: Id { ns : \"\" , name : \"TestStruct\" , }) ; } ;"); + }).to_string(), "impl ToXml for TestStruct { fn serialize < W : :: core :: fmt :: Write + ? :: core :: marker :: Sized > (& self , serializer : & mut instant_xml :: Serializer < W > ,) -> Result < () , instant_xml :: Error > { let prefix = serializer . write_start (\"TestStruct\" , \"\" , false) ? ; debug_assert_eq ! (prefix , None) ; let mut new = :: instant_xml :: ser :: Context :: < 0usize > :: default () ; new . default_ns = \"\" ; let old = serializer . push (new) ? ; serializer . end_start () ? ; match < String as ToXml > :: KIND { :: instant_xml :: Kind :: Element (_) => { self . field_1 . serialize (serializer) ? ; } :: instant_xml :: Kind :: Scalar | :: instant_xml :: Kind :: Vec => { let prefix = serializer . write_start (\"FIELD_1\" , \"\" , true) ? ; serializer . end_start () ? ; self . field_1 . serialize (serializer) ? ; serializer . write_close (prefix , \"FIELD_1\") ? ; } } match < u8 as ToXml > :: KIND { :: instant_xml :: Kind :: Element (_) => { self . field_2 . serialize (serializer) ? ; } :: instant_xml :: Kind :: Scalar | :: instant_xml :: Kind :: Vec => { let prefix = serializer . write_start (\"FIELD_2\" , \"\" , true) ? ; serializer . end_start () ? ; self . field_2 . serialize (serializer) ? ; serializer . write_close (prefix , \"FIELD_2\") ? ; } } serializer . write_close (prefix , \"TestStruct\") ? ; serializer . pop (old) ; Ok (()) } const KIND : :: instant_xml :: Kind = :: instant_xml :: Kind :: Element (:: instant_xml :: Id { ns : \"\" , name : \"TestStruct\" , }) ; } ;"); } #[test] diff --git a/instant-xml-macros/src/ser.rs b/instant-xml-macros/src/ser.rs index 84313b2..2ce955d 100644 --- a/instant-xml-macros/src/ser.rs +++ b/instant-xml-macros/src/ser.rs @@ -206,7 +206,7 @@ fn process_named_field( ::instant_xml::Kind::Element(_) => { self.#field_name.serialize(serializer)?; } - ::instant_xml::Kind::Scalar => { + ::instant_xml::Kind::Scalar | ::instant_xml::Kind::Vec => { let prefix = serializer.write_start(#tag, #ns, true)?; serializer.end_start()?; self.#field_name.serialize(serializer)?; diff --git a/instant-xml/src/impls.rs b/instant-xml/src/impls.rs index 1c876c3..ce8378b 100644 --- a/instant-xml/src/impls.rs +++ b/instant-xml/src/impls.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use std::fmt; use std::str::FromStr; -use crate::{de::Node, Deserializer, Error, FromXml, Id, Kind, Serializer, ToXml}; +use crate::{de::Node, Deserializer, Error, FromXml, Kind, Serializer, ToXml}; // Deserializer struct FromXmlStr(Option); @@ -317,7 +317,6 @@ fn decode(input: &str) -> Cow<'_, str> { Cow::Owned(result) } -const VEC_TAG: &str = "list"; const VEC_ELEMENT_TAG: &str = "element"; impl<'xml, T> FromXml<'xml> for Vec @@ -347,10 +346,7 @@ where Ok(result) } - const KIND: Kind = Kind::Element(Id { - ns: "", - name: VEC_TAG, - }); + const KIND: Kind = Kind::Vec; } impl ToXml for Vec @@ -361,9 +357,6 @@ where &self, serializer: &mut Serializer, ) -> Result<(), Error> { - let prefix = serializer.write_start(VEC_TAG, "", false)?; - serializer.end_start()?; - for i in self { let prefix = serializer.write_start(VEC_ELEMENT_TAG, "", false)?; serializer.end_start()?; @@ -371,13 +364,8 @@ where serializer.write_close(prefix, VEC_ELEMENT_TAG)?; } - serializer.write_close(prefix, VEC_TAG)?; - Ok(()) } - const KIND: Kind = Kind::Element(Id { - ns: "", - name: VEC_TAG, - }); + const KIND: Kind = Kind::Vec; } diff --git a/instant-xml/src/lib.rs b/instant-xml/src/lib.rs index 529c906..04dea5b 100644 --- a/instant-xml/src/lib.rs +++ b/instant-xml/src/lib.rs @@ -39,6 +39,7 @@ pub fn from_str<'xml, T: FromXml<'xml>>(input: &'xml str) -> Result { let id = context.element_id(&root)?; let expected = match T::KIND { Kind::Scalar => return Err(Error::UnexpectedState), + Kind::Vec => return Err(Error::UnexpectedState), Kind::Element(expected) => expected, }; @@ -99,6 +100,7 @@ pub enum Error { pub enum Kind { Scalar, Element(Id<'static>), + Vec, } impl Kind { @@ -106,6 +108,7 @@ impl Kind { match self { Kind::Scalar => field, Kind::Element(name) => *name, + Kind::Vec => field, } } } diff --git a/instant-xml/tests/entities.rs b/instant-xml/tests/entities.rs index b89a678..77c92c8 100644 --- a/instant-xml/tests/entities.rs +++ b/instant-xml/tests/entities.rs @@ -17,7 +17,7 @@ struct StructSpecialEntities<'a> { fn escape_back() { assert_eq!( from_str( - "<>&"'adsad"strstr&onetwothree" + "<>&"'adsad"strstr&onetwothree" ), Ok(StructSpecialEntities { string: String::from("<>&\"'adsad\""), @@ -30,14 +30,14 @@ fn escape_back() { // Wrong str char assert_eq!( from_str( - "<>&"'adsad"str&onetwothree" + "<>&"'adsad"str&onetwothree" ), Err::(Error::UnexpectedValue) ); // Borrowed let escape_back = from_str::( - "<>&"'adsad"strstronetwothree" + "<>&"'adsad"strstronetwothree" ) .unwrap(); @@ -47,7 +47,7 @@ fn escape_back() { // Owned let escape_back = from_str::( - "<>&"'adsad"strstr&onetwothree" + "<>&"'adsad"strstr&onetwothree" ) .unwrap(); @@ -65,6 +65,6 @@ fn special_entities() { cow: Cow::from("&\"<>\'cc"), vec: vec!["one".into(), "two".into(), "three".into()] }).unwrap(), - "&"<>'aa&"<>'bb&"<>'cconetwothree", + "&"<>'aa&"<>'bb&"<>'cconetwothree", ); }