Escape entities in context iterator
This commit is contained in:
parent
efdf9334c7
commit
edad589294
|
@ -63,7 +63,7 @@ fn deserialize_scalar_enum(
|
||||||
};
|
};
|
||||||
|
|
||||||
let serialize_as = meta.serialize_as;
|
let serialize_as = meta.serialize_as;
|
||||||
variants.extend(quote!(Some(#serialize_as) => #ident::#v_ident,));
|
variants.extend(quote!(#serialize_as => #ident::#v_ident,));
|
||||||
}
|
}
|
||||||
|
|
||||||
let generics = meta.xml_generics(BTreeSet::new());
|
let generics = meta.xml_generics(BTreeSet::new());
|
||||||
|
@ -92,14 +92,18 @@ fn deserialize_scalar_enum(
|
||||||
return Err(Error::DuplicateValue);
|
return Err(Error::DuplicateValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = match deserializer.take_str()? {
|
let cow_str = match deserializer.take_str()? {
|
||||||
#variants
|
Some(val) => val,
|
||||||
Some(val) => return Err(Error::UnexpectedValue(
|
|
||||||
format!("enum variant not found for '{}'", val)
|
|
||||||
)),
|
|
||||||
None => return Err(Error::MissingValue(#type_str)),
|
None => return Err(Error::MissingValue(#type_str)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let value = match cow_str.as_ref() {
|
||||||
|
#variants
|
||||||
|
_ => return Err(Error::UnexpectedValue(
|
||||||
|
format!("enum variant not found for '{}'", cow_str),
|
||||||
|
)),
|
||||||
|
};
|
||||||
|
|
||||||
*into = Some(value);
|
*into = Some(value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ impl<'cx, 'xml> Deserializer<'cx, 'xml> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_str(&mut self) -> Result<Option<&'xml str>, Error> {
|
pub fn take_str(&mut self) -> Result<Option<Cow<'xml, str>>, Error> {
|
||||||
loop {
|
loop {
|
||||||
match self.next() {
|
match self.next() {
|
||||||
Some(Ok(Node::AttributeValue(s))) => return Ok(Some(s)),
|
Some(Ok(Node::AttributeValue(s))) => return Ok(Some(s)),
|
||||||
|
@ -321,18 +321,23 @@ impl<'xml> Iterator for Context<'xml> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let value = match decode(value.as_str()) {
|
||||||
|
Ok(value) => value,
|
||||||
|
Err(e) => return Some(Err(e)),
|
||||||
|
};
|
||||||
|
|
||||||
self.records.push_back(Node::Attribute(Attribute {
|
self.records.push_back(Node::Attribute(Attribute {
|
||||||
prefix: match prefix.is_empty() {
|
prefix: match prefix.is_empty() {
|
||||||
true => None,
|
true => None,
|
||||||
false => Some(prefix.as_str()),
|
false => Some(prefix.as_str()),
|
||||||
},
|
},
|
||||||
local: local.as_str(),
|
local: local.as_str(),
|
||||||
value: value.as_str(),
|
value,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Token::Text { text }) => {
|
Ok(Token::Text { text }) => {
|
||||||
return Some(Ok(Node::Text(text.as_str())));
|
return Some(decode(text.as_str()).map(Node::Text));
|
||||||
}
|
}
|
||||||
Ok(Token::Declaration { .. }) => match self.stack.is_empty() {
|
Ok(Token::Declaration { .. }) => match self.stack.is_empty() {
|
||||||
false => return Some(Err(Error::UnexpectedToken(format!("{token:?}")))),
|
false => return Some(Err(Error::UnexpectedToken(format!("{token:?}")))),
|
||||||
|
@ -354,12 +359,11 @@ pub fn borrow_cow_str<'a, 'xml: 'a>(
|
||||||
return Err(Error::DuplicateValue);
|
return Err(Error::DuplicateValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = match deserializer.take_str()? {
|
match deserializer.take_str()? {
|
||||||
Some(value) => value,
|
Some(value) => into.inner = Some(value),
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
into.inner = Some(decode(value)?);
|
|
||||||
deserializer.ignore()?;
|
deserializer.ignore()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -374,7 +378,7 @@ pub fn borrow_cow_slice_u8<'xml>(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(value) = deserializer.take_str()? {
|
if let Some(value) = deserializer.take_str()? {
|
||||||
*into = Some(match decode(value)? {
|
*into = Some(match value {
|
||||||
Cow::Borrowed(v) => Cow::Borrowed(v.as_bytes()),
|
Cow::Borrowed(v) => Cow::Borrowed(v.as_bytes()),
|
||||||
Cow::Owned(v) => Cow::Owned(v.into_bytes()),
|
Cow::Owned(v) => Cow::Owned(v.into_bytes()),
|
||||||
});
|
});
|
||||||
|
@ -384,7 +388,7 @@ pub fn borrow_cow_slice_u8<'xml>(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn decode(input: &str) -> Result<Cow<'_, str>, Error> {
|
fn decode(input: &str) -> Result<Cow<'_, str>, Error> {
|
||||||
let mut result = String::with_capacity(input.len());
|
let mut result = String::with_capacity(input.len());
|
||||||
let (mut state, mut last_end) = (DecodeState::Normal, 0);
|
let (mut state, mut last_end) = (DecodeState::Normal, 0);
|
||||||
for (i, &b) in input.as_bytes().iter().enumerate() {
|
for (i, &b) in input.as_bytes().iter().enumerate() {
|
||||||
|
@ -489,12 +493,12 @@ fn valid_xml_character(c: &char) -> bool {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Node<'xml> {
|
pub enum Node<'xml> {
|
||||||
Attribute(Attribute<'xml>),
|
Attribute(Attribute<'xml>),
|
||||||
AttributeValue(&'xml str),
|
AttributeValue(Cow<'xml, str>),
|
||||||
Close {
|
Close {
|
||||||
prefix: Option<&'xml str>,
|
prefix: Option<&'xml str>,
|
||||||
local: &'xml str,
|
local: &'xml str,
|
||||||
},
|
},
|
||||||
Text(&'xml str),
|
Text(Cow<'xml, str>),
|
||||||
Open(Element<'xml>),
|
Open(Element<'xml>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,7 +523,7 @@ struct Level<'xml> {
|
||||||
pub struct Attribute<'xml> {
|
pub struct Attribute<'xml> {
|
||||||
pub prefix: Option<&'xml str>,
|
pub prefix: Option<&'xml str>,
|
||||||
pub local: &'xml str,
|
pub local: &'xml str,
|
||||||
pub value: &'xml str,
|
pub value: Cow<'xml, str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -8,7 +8,6 @@ use std::{any::type_name, marker::PhantomData};
|
||||||
#[cfg(feature = "chrono")]
|
#[cfg(feature = "chrono")]
|
||||||
use chrono::{DateTime, NaiveDate, Utc};
|
use chrono::{DateTime, NaiveDate, Utc};
|
||||||
|
|
||||||
use crate::de::decode;
|
|
||||||
use crate::{Accumulate, Deserializer, Error, FromXml, Id, Kind, Serializer, ToXml};
|
use crate::{Accumulate, Deserializer, Error, FromXml, Id, Kind, Serializer, ToXml};
|
||||||
|
|
||||||
// Deserializer
|
// Deserializer
|
||||||
|
@ -26,7 +25,7 @@ pub fn from_xml_str<T: FromStr>(
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
match T::from_str(value) {
|
match T::from_str(value.as_ref()) {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
*into = Some(value);
|
*into = Some(value);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -63,7 +62,7 @@ impl<'xml, T: FromStr> FromXml<'xml> for FromXmlStr<T> {
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
match T::from_str(value) {
|
match T::from_str(value.as_ref()) {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
*into = Some(FromXmlStr(value));
|
*into = Some(FromXmlStr(value));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -102,7 +101,7 @@ impl<'xml> FromXml<'xml> for bool {
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = match value {
|
let value = match value.as_ref() {
|
||||||
"true" | "1" => true,
|
"true" | "1" => true,
|
||||||
"false" | "0" => false,
|
"false" | "0" => false,
|
||||||
val => {
|
val => {
|
||||||
|
@ -271,7 +270,7 @@ impl<'xml> FromXml<'xml> for String {
|
||||||
}
|
}
|
||||||
|
|
||||||
match deserializer.take_str()? {
|
match deserializer.take_str()? {
|
||||||
Some(value) => *into = Some(decode(value)?.into_owned()),
|
Some(value) => *into = Some(value.into_owned()),
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +304,7 @@ impl<'xml, 'a> FromXml<'xml> for Cow<'a, str> {
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
into.inner = Some(decode(value)?.into_owned().into());
|
into.inner = Some(value.into_owned().into());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,7 +607,7 @@ impl<'xml> FromXml<'xml> for DateTime<Utc> {
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
match DateTime::parse_from_rfc3339(value) {
|
match DateTime::parse_from_rfc3339(value.as_ref()) {
|
||||||
Ok(dt) if dt.timezone().utc_minus_local() == 0 => {
|
Ok(dt) if dt.timezone().utc_minus_local() == 0 => {
|
||||||
*into = Some(dt.with_timezone(&Utc));
|
*into = Some(dt.with_timezone(&Utc));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -670,7 +669,7 @@ impl<'xml> FromXml<'xml> for NaiveDate {
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
match NaiveDate::parse_from_str(value, "%Y-%m-%d") {
|
match NaiveDate::parse_from_str(value.as_ref(), "%Y-%m-%d") {
|
||||||
Ok(d) => {
|
Ok(d) => {
|
||||||
*into = Some(d);
|
*into = Some(d);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in New Issue