Add support for Vec<T>
This commit is contained in:
parent
44f8a2cc6d
commit
dc9eb50e6c
|
@ -2,7 +2,7 @@ use std::borrow::Cow;
|
|||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::{Deserializer, Error, FromXml, Kind, Serializer, ToXml};
|
||||
use crate::{de::Node, Deserializer, Error, FromXml, Id, Kind, Serializer, ToXml};
|
||||
|
||||
// Deserializer
|
||||
struct FromXmlStr<T: FromStr>(Option<T>);
|
||||
|
@ -316,3 +316,68 @@ 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<T>
|
||||
where
|
||||
T: FromXml<'xml>,
|
||||
{
|
||||
fn deserialize<'cx>(deserializer: &'cx mut Deserializer<'cx, 'xml>) -> Result<Self, Error> {
|
||||
let mut result = Self::new();
|
||||
|
||||
while let Some(Ok(node)) = deserializer.next() {
|
||||
match node {
|
||||
Node::Open(data) => {
|
||||
let id = deserializer.element_id(&data)?;
|
||||
|
||||
match id.name {
|
||||
VEC_ELEMENT_TAG => {
|
||||
let mut nested = deserializer.nested(data);
|
||||
result.push(<T as FromXml<'xml>>::deserialize(&mut nested)?)
|
||||
}
|
||||
_ => return Err(Error::UnexpectedState),
|
||||
}
|
||||
}
|
||||
_ => return Err(Error::UnexpectedState),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
const KIND: Kind = Kind::Element(Id {
|
||||
ns: "",
|
||||
name: VEC_TAG,
|
||||
});
|
||||
}
|
||||
|
||||
impl<T> ToXml for Vec<T>
|
||||
where
|
||||
T: ToXml,
|
||||
{
|
||||
fn serialize<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
serializer: &mut Serializer<W>,
|
||||
) -> 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()?;
|
||||
i.serialize(serializer)?;
|
||||
serializer.write_close(prefix, VEC_ELEMENT_TAG)?;
|
||||
}
|
||||
|
||||
serializer.write_close(prefix, VEC_TAG)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
const KIND: Kind = Kind::Element(Id {
|
||||
ns: "",
|
||||
name: VEC_TAG,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,32 +10,34 @@ struct StructSpecialEntities<'a> {
|
|||
string: String,
|
||||
str: &'a str,
|
||||
cow: Cow<'a, str>,
|
||||
vec: Vec<String>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escape_back() {
|
||||
assert_eq!(
|
||||
from_str(
|
||||
"<StructSpecialEntities xmlns=\"URI\"><string><>&"'adsad"</string><str>str</str><cow>str&</cow></StructSpecialEntities>"
|
||||
"<StructSpecialEntities xmlns=\"URI\"><string><>&"'adsad"</string><str>str</str><cow>str&</cow><list xmlns=\"\"><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></list></StructSpecialEntities>"
|
||||
),
|
||||
Ok(StructSpecialEntities {
|
||||
string: String::from("<>&\"'adsad\""),
|
||||
str: "str",
|
||||
cow: Cow::Owned("str&".to_string()),
|
||||
vec: vec!["one".into(), "two".into(), "three".into()]
|
||||
})
|
||||
);
|
||||
|
||||
// Wrong str char
|
||||
assert_eq!(
|
||||
from_str(
|
||||
"<StructSpecialEntities xmlns=\"URI\"><string><>&"'adsad"</string><str>str&</str></StructSpecialEntities>"
|
||||
"<StructSpecialEntities xmlns=\"URI\"><string><>&"'adsad"</string><str>str&</str><list xmlns=\"\"><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></list></StructSpecialEntities>"
|
||||
),
|
||||
Err::<StructSpecialEntities, _>(Error::UnexpectedValue)
|
||||
);
|
||||
|
||||
// Borrowed
|
||||
let escape_back = from_str::<StructSpecialEntities>(
|
||||
"<StructSpecialEntities xmlns=\"URI\"><string><>&"'adsad"</string><str>str</str><cow>str</cow></StructSpecialEntities>"
|
||||
"<StructSpecialEntities xmlns=\"URI\"><string><>&"'adsad"</string><str>str</str><cow>str</cow><list xmlns=\"\"><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></list></StructSpecialEntities>"
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -45,7 +47,7 @@ fn escape_back() {
|
|||
|
||||
// Owned
|
||||
let escape_back = from_str::<StructSpecialEntities>(
|
||||
"<StructSpecialEntities xmlns=\"URI\"><string><>&"'adsad"</string><str>str</str><cow>str&</cow></StructSpecialEntities>"
|
||||
"<StructSpecialEntities xmlns=\"URI\"><string><>&"'adsad"</string><str>str</str><cow>str&</cow><list xmlns=\"\"><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></list></StructSpecialEntities>"
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -61,7 +63,8 @@ fn special_entities() {
|
|||
string: "&\"<>\'aa".to_string(),
|
||||
str: "&\"<>\'bb",
|
||||
cow: Cow::from("&\"<>\'cc"),
|
||||
vec: vec!["one".into(), "two".into(), "three".into()]
|
||||
}).unwrap(),
|
||||
"<StructSpecialEntities xmlns=\"URI\"><string>&"<>'aa</string><str>&"<>'bb</str><cow>&"<>'cc</cow></StructSpecialEntities>",
|
||||
"<StructSpecialEntities xmlns=\"URI\"><string>&"<>'aa</string><str>&"<>'bb</str><cow>&"<>'cc</cow><list xmlns=\"\"><element xmlns=\"\">one</element><element xmlns=\"\">two</element><element xmlns=\"\">three</element></list></StructSpecialEntities>",
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue