Use field name as tag for `Vec` serialization

This commit is contained in:
rsdy 2022-09-29 17:12:08 +01:00 committed by Dirkjan Ochtman
parent dc9eb50e6c
commit 4d627b514a
5 changed files with 13 additions and 22 deletions

View File

@ -820,7 +820,7 @@ mod tests {
field_1: String, field_1: String,
field_2: u8, 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] #[test]

View File

@ -206,7 +206,7 @@ fn process_named_field(
::instant_xml::Kind::Element(_) => { ::instant_xml::Kind::Element(_) => {
self.#field_name.serialize(serializer)?; 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)?; let prefix = serializer.write_start(#tag, #ns, true)?;
serializer.end_start()?; serializer.end_start()?;
self.#field_name.serialize(serializer)?; self.#field_name.serialize(serializer)?;

View File

@ -2,7 +2,7 @@ use std::borrow::Cow;
use std::fmt; use std::fmt;
use std::str::FromStr; 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 // Deserializer
struct FromXmlStr<T: FromStr>(Option<T>); struct FromXmlStr<T: FromStr>(Option<T>);
@ -317,7 +317,6 @@ fn decode(input: &str) -> Cow<'_, str> {
Cow::Owned(result) Cow::Owned(result)
} }
const VEC_TAG: &str = "list";
const VEC_ELEMENT_TAG: &str = "element"; const VEC_ELEMENT_TAG: &str = "element";
impl<'xml, T> FromXml<'xml> for Vec<T> impl<'xml, T> FromXml<'xml> for Vec<T>
@ -347,10 +346,7 @@ where
Ok(result) Ok(result)
} }
const KIND: Kind = Kind::Element(Id { const KIND: Kind = Kind::Vec;
ns: "",
name: VEC_TAG,
});
} }
impl<T> ToXml for Vec<T> impl<T> ToXml for Vec<T>
@ -361,9 +357,6 @@ where
&self, &self,
serializer: &mut Serializer<W>, serializer: &mut Serializer<W>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let prefix = serializer.write_start(VEC_TAG, "", false)?;
serializer.end_start()?;
for i in self { for i in self {
let prefix = serializer.write_start(VEC_ELEMENT_TAG, "", false)?; let prefix = serializer.write_start(VEC_ELEMENT_TAG, "", false)?;
serializer.end_start()?; serializer.end_start()?;
@ -371,13 +364,8 @@ where
serializer.write_close(prefix, VEC_ELEMENT_TAG)?; serializer.write_close(prefix, VEC_ELEMENT_TAG)?;
} }
serializer.write_close(prefix, VEC_TAG)?;
Ok(()) Ok(())
} }
const KIND: Kind = Kind::Element(Id { const KIND: Kind = Kind::Vec;
ns: "",
name: VEC_TAG,
});
} }

View File

@ -39,6 +39,7 @@ pub fn from_str<'xml, T: FromXml<'xml>>(input: &'xml str) -> Result<T, Error> {
let id = context.element_id(&root)?; let id = context.element_id(&root)?;
let expected = match T::KIND { let expected = match T::KIND {
Kind::Scalar => return Err(Error::UnexpectedState), Kind::Scalar => return Err(Error::UnexpectedState),
Kind::Vec => return Err(Error::UnexpectedState),
Kind::Element(expected) => expected, Kind::Element(expected) => expected,
}; };
@ -99,6 +100,7 @@ pub enum Error {
pub enum Kind { pub enum Kind {
Scalar, Scalar,
Element(Id<'static>), Element(Id<'static>),
Vec,
} }
impl Kind { impl Kind {
@ -106,6 +108,7 @@ impl Kind {
match self { match self {
Kind::Scalar => field, Kind::Scalar => field,
Kind::Element(name) => *name, Kind::Element(name) => *name,
Kind::Vec => field,
} }
} }
} }

View File

@ -17,7 +17,7 @@ struct StructSpecialEntities<'a> {
fn escape_back() { fn escape_back() {
assert_eq!( assert_eq!(
from_str( from_str(
"<StructSpecialEntities xmlns=\"URI\"><string>&lt;&gt;&amp;&quot;&apos;adsad&quot;</string><str>str</str><cow>str&amp;</cow><list xmlns=\"\"><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></list></StructSpecialEntities>" "<StructSpecialEntities xmlns=\"URI\"><string>&lt;&gt;&amp;&quot;&apos;adsad&quot;</string><str>str</str><cow>str&amp;</cow><vec><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></vec></StructSpecialEntities>"
), ),
Ok(StructSpecialEntities { Ok(StructSpecialEntities {
string: String::from("<>&\"'adsad\""), string: String::from("<>&\"'adsad\""),
@ -30,14 +30,14 @@ fn escape_back() {
// Wrong str char // Wrong str char
assert_eq!( assert_eq!(
from_str( from_str(
"<StructSpecialEntities xmlns=\"URI\"><string>&lt;&gt;&amp;&quot;&apos;adsad&quot;</string><str>str&amp;</str><list xmlns=\"\"><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></list></StructSpecialEntities>" "<StructSpecialEntities xmlns=\"URI\"><string>&lt;&gt;&amp;&quot;&apos;adsad&quot;</string><str>str&amp;</str><vec><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></vec></StructSpecialEntities>"
), ),
Err::<StructSpecialEntities, _>(Error::UnexpectedValue) Err::<StructSpecialEntities, _>(Error::UnexpectedValue)
); );
// Borrowed // Borrowed
let escape_back = from_str::<StructSpecialEntities>( let escape_back = from_str::<StructSpecialEntities>(
"<StructSpecialEntities xmlns=\"URI\"><string>&lt;&gt;&amp;&quot;&apos;adsad&quot;</string><str>str</str><cow>str</cow><list xmlns=\"\"><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></list></StructSpecialEntities>" "<StructSpecialEntities xmlns=\"URI\"><string>&lt;&gt;&amp;&quot;&apos;adsad&quot;</string><str>str</str><cow>str</cow><vec><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></vec></StructSpecialEntities>"
) )
.unwrap(); .unwrap();
@ -47,7 +47,7 @@ fn escape_back() {
// Owned // Owned
let escape_back = from_str::<StructSpecialEntities>( let escape_back = from_str::<StructSpecialEntities>(
"<StructSpecialEntities xmlns=\"URI\"><string>&lt;&gt;&amp;&quot;&apos;adsad&quot;</string><str>str</str><cow>str&amp;</cow><list xmlns=\"\"><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></list></StructSpecialEntities>" "<StructSpecialEntities xmlns=\"URI\"><string>&lt;&gt;&amp;&quot;&apos;adsad&quot;</string><str>str</str><cow>str&amp;</cow><vec><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></vec></StructSpecialEntities>"
) )
.unwrap(); .unwrap();
@ -65,6 +65,6 @@ fn special_entities() {
cow: Cow::from("&\"<>\'cc"), cow: Cow::from("&\"<>\'cc"),
vec: vec!["one".into(), "two".into(), "three".into()] vec: vec!["one".into(), "two".into(), "three".into()]
}).unwrap(), }).unwrap(),
"<StructSpecialEntities xmlns=\"URI\"><string>&amp;&quot;&lt;&gt;&apos;aa</string><str>&amp;&quot;&lt;&gt;&apos;bb</str><cow>&amp;&quot;&lt;&gt;&apos;cc</cow><list xmlns=\"\"><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></list></StructSpecialEntities>", "<StructSpecialEntities xmlns=\"URI\"><string>&amp;&quot;&lt;&gt;&apos;aa</string><str>&amp;&quot;&lt;&gt;&apos;bb</str><cow>&amp;&quot;&lt;&gt;&apos;cc</cow><vec><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></vec></StructSpecialEntities>",
); );
} }