From dc9eb50e6cd6efe540526bc561c1aa381c38a2a8 Mon Sep 17 00:00:00 2001
From: rsdy
Date: Wed, 28 Sep 2022 18:58:57 +0100
Subject: [PATCH] Add support for Vec
---
instant-xml/src/impls.rs | 67 ++++++++++++++++++++++++++++++++++-
instant-xml/tests/entities.rs | 13 ++++---
2 files changed, 74 insertions(+), 6 deletions(-)
diff --git a/instant-xml/src/impls.rs b/instant-xml/src/impls.rs
index 03e5149..1c876c3 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::{Deserializer, Error, FromXml, Kind, Serializer, ToXml};
+use crate::{de::Node, Deserializer, Error, FromXml, Id, Kind, Serializer, ToXml};
// Deserializer
struct FromXmlStr(Option);
@@ -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
+where
+ T: FromXml<'xml>,
+{
+ fn deserialize<'cx>(deserializer: &'cx mut Deserializer<'cx, 'xml>) -> Result {
+ 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(>::deserialize(&mut nested)?)
+ }
+ _ => return Err(Error::UnexpectedState),
+ }
+ }
+ _ => return Err(Error::UnexpectedState),
+ }
+ }
+
+ Ok(result)
+ }
+
+ const KIND: Kind = Kind::Element(Id {
+ ns: "",
+ name: VEC_TAG,
+ });
+}
+
+impl ToXml for Vec
+where
+ T: ToXml,
+{
+ fn serialize(
+ &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()?;
+ 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,
+ });
+}
diff --git a/instant-xml/tests/entities.rs b/instant-xml/tests/entities.rs
index 91c57f6..b89a678 100644
--- a/instant-xml/tests/entities.rs
+++ b/instant-xml/tests/entities.rs
@@ -10,32 +10,34 @@ struct StructSpecialEntities<'a> {
string: String,
str: &'a str,
cow: Cow<'a, str>,
+ vec: Vec,
}
#[test]
fn escape_back() {
assert_eq!(
from_str(
- "<>&"'adsad"strstr&"
+ "<>&"'adsad"strstr&onetwothree
"
),
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(
- "<>&"'adsad"str&"
+ "<>&"'adsad"str&onetwothree
"
),
Err::(Error::UnexpectedValue)
);
// Borrowed
let escape_back = from_str::(
- "<>&"'adsad"strstr"
+ "<>&"'adsad"strstronetwothree
"
)
.unwrap();
@@ -45,7 +47,7 @@ fn escape_back() {
// Owned
let escape_back = from_str::(
- "<>&"'adsad"strstr&"
+ "<>&"'adsad"strstr&onetwothree
"
)
.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(),
- "&"<>'aa&"<>'bb&"<>'cc",
+ "&"<>'aa&"<>'bb&"<>'cconetwothree
",
);
}