diff --git a/instant-xml-macros/src/de.rs b/instant-xml-macros/src/de.rs index 4ba665e..a8e7cd5 100644 --- a/instant-xml-macros/src/de.rs +++ b/instant-xml-macros/src/de.rs @@ -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))), } } diff --git a/instant-xml/src/de.rs b/instant-xml/src/de.rs index 77ba561..2526c98 100644 --- a/instant-xml/src/de.rs +++ b/instant-xml/src/de.rs @@ -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))), } } diff --git a/instant-xml/src/impls.rs b/instant-xml/src/impls.rs index 2773b21..b4fa659 100644 --- a/instant-xml/src/impls.rs +++ b/instant-xml/src/impls.rs @@ -341,14 +341,14 @@ where let mut nested = deserializer.nested(data); result.push(>::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(>::deserialize(&mut nested)?) } - _ => return Err(Error::UnexpectedState), + _ => return Err(Error::UnexpectedState("unexpected node for list")), } } diff --git a/instant-xml/src/lib.rs b/instant-xml/src/lib.rs index cf4281e..fd1cf2a 100644 --- a/instant-xml/src/lib.rs +++ b/instant-xml/src/lib.rs @@ -49,8 +49,8 @@ pub fn from_str<'xml, T: FromXml<'xml>>(input: &'xml str) -> Result { 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")] diff --git a/instant-xml/src/ser.rs b/instant-xml/src/ser.rs index daf00ea..aafecd4 100644 --- a/instant-xml/src/ser.rs +++ b/instant-xml/src/ser.rs @@ -35,7 +35,7 @@ impl<'xml, W: fmt::Write + ?Sized> Serializer<'xml, W> { scalar: bool, ) -> Result, 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(&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(&mut self, new: Context) -> Result, Error> { if self.state != State::Attribute { - return Err(Error::UnexpectedState); + return Err(Error::UnexpectedState("invalid state for attribute")); } let mut old = Context::default();