Improve error reporting
This commit is contained in:
parent
f6e22b3e31
commit
eb2cfd59f9
|
@ -132,7 +132,7 @@ fn deserialize_wrapped_enum(
|
||||||
|
|
||||||
let data = match node {
|
let data = match node {
|
||||||
Node::Open(data) => data,
|
Node::Open(data) => data,
|
||||||
_ => return Err(Error::UnexpectedState),
|
_ => return Err(Error::UnexpectedState("unexpected node type for wrapped enum variant")),
|
||||||
};
|
};
|
||||||
|
|
||||||
let id = deserializer.element_id(&data)?;
|
let id = deserializer.element_id(&data)?;
|
||||||
|
@ -141,7 +141,7 @@ fn deserialize_wrapped_enum(
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(_) = deserializer.next() {
|
if let Some(_) = deserializer.next() {
|
||||||
return Err(Error::UnexpectedState);
|
return Err(Error::UnexpectedState("unexpected node after wrapped enum variant"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(value)
|
Ok(value)
|
||||||
|
@ -278,7 +278,7 @@ fn deserialize_struct(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return Err(Error::UnexpectedState),
|
node => return Err(Error::UnexpectedNode(format!("{:?}", node))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,11 @@ impl<'cx, 'xml> Deserializer<'cx, 'xml> {
|
||||||
|
|
||||||
if element {
|
if element {
|
||||||
match self.next() {
|
match self.next() {
|
||||||
Some(Ok(_)) => return Err(Error::UnexpectedState),
|
Some(Ok(_)) => {
|
||||||
|
return Err(Error::UnexpectedState(
|
||||||
|
"found element while expecting scalar",
|
||||||
|
))
|
||||||
|
}
|
||||||
Some(Err(e)) => return Err(e),
|
Some(Err(e)) => return Err(e),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +116,7 @@ impl<'xml> Iterator for Deserializer<'_, 'xml> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Err(Error::UnexpectedState))
|
Some(Err(Error::UnexpectedState("close element mismatch")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +137,7 @@ impl<'xml> Context<'xml> {
|
||||||
let root = match new.next() {
|
let root = match new.next() {
|
||||||
Some(result) => match result? {
|
Some(result) => match result? {
|
||||||
Node::Open(element) => element,
|
Node::Open(element) => element,
|
||||||
_ => return Err(Error::UnexpectedState),
|
_ => return Err(Error::UnexpectedState("first node does not open element")),
|
||||||
},
|
},
|
||||||
None => return Err(Error::UnexpectedEndOfStream),
|
None => return Err(Error::UnexpectedEndOfStream),
|
||||||
};
|
};
|
||||||
|
@ -217,7 +221,11 @@ impl<'xml> Iterator for Context<'xml> {
|
||||||
ElementEnd::Open => {
|
ElementEnd::Open => {
|
||||||
let level = match current {
|
let level = match current {
|
||||||
Some(level) => level,
|
Some(level) => level,
|
||||||
None => return Some(Err(Error::UnexpectedState)),
|
None => {
|
||||||
|
return Some(Err(Error::UnexpectedState(
|
||||||
|
"opening element with no parent",
|
||||||
|
)))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let element = Element {
|
let element = Element {
|
||||||
|
@ -232,7 +240,11 @@ impl<'xml> Iterator for Context<'xml> {
|
||||||
ElementEnd::Close(prefix, v) => {
|
ElementEnd::Close(prefix, v) => {
|
||||||
let level = match self.stack.pop() {
|
let level = match self.stack.pop() {
|
||||||
Some(level) => level,
|
Some(level) => level,
|
||||||
None => return Some(Err(Error::UnexpectedState)),
|
None => {
|
||||||
|
return Some(Err(Error::UnexpectedState(
|
||||||
|
"closing element without parent",
|
||||||
|
)))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let prefix = (!prefix.is_empty()).then_some(prefix.as_str());
|
let prefix = (!prefix.is_empty()).then_some(prefix.as_str());
|
||||||
|
@ -243,7 +255,9 @@ impl<'xml> Iterator for Context<'xml> {
|
||||||
local: level.local,
|
local: level.local,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
false => return Some(Err(Error::UnexpectedState)),
|
false => {
|
||||||
|
return Some(Err(Error::UnexpectedState("close element mismatch")))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ElementEnd::Empty => {
|
ElementEnd::Empty => {
|
||||||
|
@ -259,14 +273,22 @@ impl<'xml> Iterator for Context<'xml> {
|
||||||
if prefix.is_empty() && local.as_str() == "xmlns" {
|
if prefix.is_empty() && local.as_str() == "xmlns" {
|
||||||
match &mut current {
|
match &mut current {
|
||||||
Some(level) => level.default_ns = Some(value.as_str()),
|
Some(level) => level.default_ns = Some(value.as_str()),
|
||||||
None => return Some(Err(Error::UnexpectedState)),
|
None => {
|
||||||
|
return Some(Err(Error::UnexpectedState(
|
||||||
|
"attribute without element context",
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if prefix.as_str() == "xmlns" {
|
} else if prefix.as_str() == "xmlns" {
|
||||||
match &mut current {
|
match &mut current {
|
||||||
Some(level) => {
|
Some(level) => {
|
||||||
level.prefixes.insert(local.as_str(), value.as_str());
|
level.prefixes.insert(local.as_str(), value.as_str());
|
||||||
}
|
}
|
||||||
None => return Some(Err(Error::UnexpectedState)),
|
None => {
|
||||||
|
return Some(Err(Error::UnexpectedState(
|
||||||
|
"attribute without element context",
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let prefix = (!prefix.is_empty()).then_some(prefix.as_str());
|
let prefix = (!prefix.is_empty()).then_some(prefix.as_str());
|
||||||
|
@ -280,7 +302,7 @@ impl<'xml> Iterator for Context<'xml> {
|
||||||
Ok(Token::Text { text }) => {
|
Ok(Token::Text { text }) => {
|
||||||
return Some(Ok(Node::Text(text.as_str())));
|
return Some(Ok(Node::Text(text.as_str())));
|
||||||
}
|
}
|
||||||
Ok(_) => return Some(Err(Error::UnexpectedToken)),
|
Ok(token) => return Some(Err(Error::UnexpectedToken(format!("{:?}", token)))),
|
||||||
Err(e) => return Some(Err(Error::Parse(e))),
|
Err(e) => return Some(Err(Error::Parse(e))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -341,14 +341,14 @@ where
|
||||||
let mut nested = deserializer.nested(data);
|
let mut nested = deserializer.nested(data);
|
||||||
result.push(<T as FromXml<'xml>>::deserialize(&mut nested)?)
|
result.push(<T as FromXml<'xml>>::deserialize(&mut nested)?)
|
||||||
}
|
}
|
||||||
_ => return Err(Error::UnexpectedState),
|
_ => return Err(Error::UnexpectedState("unexpected list element name")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Kind::Vec | Kind::Element(_), Node::Open(data)) => {
|
(Kind::Vec | Kind::Element(_), Node::Open(data)) => {
|
||||||
let mut nested = deserializer.nested(data);
|
let mut nested = deserializer.nested(data);
|
||||||
result.push(<T as FromXml<'xml>>::deserialize(&mut nested)?)
|
result.push(<T as FromXml<'xml>>::deserialize(&mut nested)?)
|
||||||
}
|
}
|
||||||
_ => return Err(Error::UnexpectedState),
|
_ => return Err(Error::UnexpectedState("unexpected node for list")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,8 @@ pub fn from_str<'xml, T: FromXml<'xml>>(input: &'xml str) -> Result<T, Error> {
|
||||||
let (mut context, root) = Context::new(input)?;
|
let (mut context, root) = Context::new(input)?;
|
||||||
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("found scalar as root")),
|
||||||
Kind::Vec => return Err(Error::UnexpectedState),
|
Kind::Vec => return Err(Error::UnexpectedState("found list as root")),
|
||||||
Kind::Element(expected) => expected,
|
Kind::Element(expected) => expected,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,12 +96,14 @@ pub enum Error {
|
||||||
MissingTag,
|
MissingTag,
|
||||||
#[error("missing value")]
|
#[error("missing value")]
|
||||||
MissingValue,
|
MissingValue,
|
||||||
#[error("unexpected token")]
|
#[error("unexpected token: {0}")]
|
||||||
UnexpectedToken,
|
UnexpectedToken(String),
|
||||||
#[error("missing prefix")]
|
#[error("missing prefix")]
|
||||||
MissingdPrefix,
|
MissingdPrefix,
|
||||||
#[error("unexpected state")]
|
#[error("unexpected node: {0}")]
|
||||||
UnexpectedState,
|
UnexpectedNode(String),
|
||||||
|
#[error("unexpected state: {0}")]
|
||||||
|
UnexpectedState(&'static str),
|
||||||
#[error("expected scalar")]
|
#[error("expected scalar")]
|
||||||
ExpectedScalar,
|
ExpectedScalar,
|
||||||
#[error("wrong namespace")]
|
#[error("wrong namespace")]
|
||||||
|
|
|
@ -35,7 +35,7 @@ impl<'xml, W: fmt::Write + ?Sized> Serializer<'xml, W> {
|
||||||
scalar: bool,
|
scalar: bool,
|
||||||
) -> Result<Option<&'static str>, Error> {
|
) -> Result<Option<&'static str>, Error> {
|
||||||
if self.state != State::Element {
|
if self.state != State::Element {
|
||||||
return Err(Error::UnexpectedState);
|
return Err(Error::UnexpectedState("invalid state for element start"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let prefix = match ns == self.default_ns {
|
let prefix = match ns == self.default_ns {
|
||||||
|
@ -70,13 +70,16 @@ impl<'xml, W: fmt::Write + ?Sized> Serializer<'xml, W> {
|
||||||
value: &V,
|
value: &V,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if self.state != State::Attribute {
|
if self.state != State::Attribute {
|
||||||
return Err(Error::UnexpectedState);
|
return Err(Error::UnexpectedState("invalid state for attribute"));
|
||||||
}
|
}
|
||||||
|
|
||||||
match ns == self.default_ns {
|
match ns == self.default_ns {
|
||||||
true => self.output.write_fmt(format_args!(" {name}=\""))?,
|
true => self.output.write_fmt(format_args!(" {name}=\""))?,
|
||||||
false => {
|
false => {
|
||||||
let prefix = self.prefixes.get(ns).ok_or(dbg!(Error::UnexpectedState))?;
|
let prefix = self
|
||||||
|
.prefixes
|
||||||
|
.get(ns)
|
||||||
|
.ok_or(Error::UnexpectedState("unknown prefix"))?;
|
||||||
self.output.write_fmt(format_args!(" {prefix}:{name}=\""))?;
|
self.output.write_fmt(format_args!(" {prefix}:{name}=\""))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +93,7 @@ impl<'xml, W: fmt::Write + ?Sized> Serializer<'xml, W> {
|
||||||
|
|
||||||
pub fn write_str<V: fmt::Display + ?Sized>(&mut self, value: &V) -> Result<(), Error> {
|
pub fn write_str<V: fmt::Display + ?Sized>(&mut self, value: &V) -> Result<(), Error> {
|
||||||
if !matches!(self.state, State::Element | State::Scalar) {
|
if !matches!(self.state, State::Element | State::Scalar) {
|
||||||
return Err(Error::UnexpectedState);
|
return Err(Error::UnexpectedState("invalid state for scalar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.output.write_fmt(format_args!("{}", value))?;
|
self.output.write_fmt(format_args!("{}", value))?;
|
||||||
|
@ -100,7 +103,7 @@ impl<'xml, W: fmt::Write + ?Sized> Serializer<'xml, W> {
|
||||||
|
|
||||||
pub fn end_start(&mut self) -> Result<(), Error> {
|
pub fn end_start(&mut self) -> Result<(), Error> {
|
||||||
if self.state != State::Attribute {
|
if self.state != State::Attribute {
|
||||||
return Err(Error::UnexpectedState);
|
return Err(Error::UnexpectedState("invalid state for element end"));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.output.write_char('>')?;
|
self.output.write_char('>')?;
|
||||||
|
@ -110,7 +113,7 @@ impl<'xml, W: fmt::Write + ?Sized> Serializer<'xml, W> {
|
||||||
|
|
||||||
pub fn write_close(&mut self, prefix: Option<&str>, name: &str) -> Result<(), Error> {
|
pub fn write_close(&mut self, prefix: Option<&str>, name: &str) -> Result<(), Error> {
|
||||||
if self.state != State::Element {
|
if self.state != State::Element {
|
||||||
return Err(Error::UnexpectedState);
|
return Err(Error::UnexpectedState("invalid state for close element"));
|
||||||
}
|
}
|
||||||
|
|
||||||
match prefix {
|
match prefix {
|
||||||
|
@ -123,7 +126,7 @@ impl<'xml, W: fmt::Write + ?Sized> Serializer<'xml, W> {
|
||||||
|
|
||||||
pub fn push<const N: usize>(&mut self, new: Context<N>) -> Result<Context<N>, Error> {
|
pub fn push<const N: usize>(&mut self, new: Context<N>) -> Result<Context<N>, Error> {
|
||||||
if self.state != State::Attribute {
|
if self.state != State::Attribute {
|
||||||
return Err(Error::UnexpectedState);
|
return Err(Error::UnexpectedState("invalid state for attribute"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut old = Context::default();
|
let mut old = Context::default();
|
||||||
|
|
Loading…
Reference in New Issue