Create streamlined API for taking value out deserializer

This commit is contained in:
Dirkjan Ochtman 2022-09-07 09:28:59 +02:00
parent cd37e306ad
commit 744faa1225
2 changed files with 27 additions and 40 deletions

View File

@ -25,6 +25,26 @@ impl<'cx, 'xml> Deserializer<'cx, 'xml> {
} }
} }
pub fn take_str(&mut self) -> Result<&'xml str, Error> {
let (value, element) = match self.next() {
Some(Ok(Node::AttributeValue(s))) => (s, false),
Some(Ok(Node::Element(s))) => (s, true),
Some(Ok(_)) => return Err(Error::ExpectedScalar),
Some(Err(e)) => return Err(e),
None => return Ok(""),
};
if element {
match self.next() {
Some(Ok(_)) => return Err(Error::UnexpectedState),
Some(Err(e)) => return Err(e),
_ => {}
}
}
Ok(value)
}
pub fn nested<'a>(&'a mut self, element: Element<'xml>) -> Deserializer<'a, 'xml> pub fn nested<'a>(&'a mut self, element: Element<'xml>) -> Deserializer<'a, 'xml>
where where
'cx: 'a, 'cx: 'a,

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::{Kind, Node}; use crate::de::Kind;
use crate::ser::FieldAttribute; use crate::ser::FieldAttribute;
use crate::{Deserializer, Error, FromXml, Serializer, ToXml}; use crate::{Deserializer, Error, FromXml, Serializer, ToXml};
@ -11,30 +11,13 @@ struct FromXmlStr<T: FromStr>(Option<T>);
impl<'xml, T: FromStr> FromXml<'xml> for FromXmlStr<T> { impl<'xml, T: FromStr> FromXml<'xml> for FromXmlStr<T> {
fn deserialize(deserializer: &mut Deserializer<'_, 'xml>) -> Result<Self, Error> { fn deserialize(deserializer: &mut Deserializer<'_, 'xml>) -> Result<Self, Error> {
let (value, element) = match deserializer.next() { let value = deserializer.take_str()?;
Some(Ok(Node::AttributeValue(s))) => (s, false), match T::from_str(value) {
Some(Ok(Node::Element(s))) => (s, true), Ok(value) => Ok(Self(Some(value))),
Some(Ok(_)) => return Err(Error::ExpectedScalar), Err(_) => Err(Error::UnexpectedValue),
Some(Err(e)) => return Err(e),
None => return Ok(Self(None)),
};
let value = match T::from_str(value) {
Ok(value) => value,
Err(_) => return Err(Error::UnexpectedValue),
};
if element {
match deserializer.next() {
Some(Ok(_)) => return Err(Error::UnexpectedState),
Some(Err(e)) => return Err(e),
_ => {}
} }
} }
Ok(Self(Some(value)))
}
const KIND: Kind = Kind::Scalar; const KIND: Kind = Kind::Scalar;
} }
@ -153,24 +136,8 @@ impl<'xml> FromXml<'xml> for &'xml str {
impl<'xml> FromXml<'xml> for Cow<'xml, str> { impl<'xml> FromXml<'xml> for Cow<'xml, str> {
fn deserialize(deserializer: &mut Deserializer<'_, 'xml>) -> Result<Self, Error> { fn deserialize(deserializer: &mut Deserializer<'_, 'xml>) -> Result<Self, Error> {
let (value, element) = match deserializer.next() { let value = deserializer.take_str()?;
Some(Ok(Node::AttributeValue(s))) => (s, false), Ok(escape_back(value))
Some(Ok(Node::Element(s))) => (s, true),
Some(Ok(_)) => return Err(Error::ExpectedScalar),
Some(Err(e)) => return Err(e),
None => return Err(Error::MissingValue),
};
let value = escape_back(value);
if element {
match deserializer.next() {
Some(Ok(_)) => return Err(Error::UnexpectedState),
Some(Err(e)) => return Err(e),
_ => {}
}
}
Ok(value)
} }
const KIND: Kind = Kind::Scalar; const KIND: Kind = Kind::Scalar;