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