parsers: use Error type from xso
This is a large change and as such, it needs good motivation. Let me remind you of the ultimate goal: we want a derive macro which allows us to FromXml/IntoXml, and that derive macro should be usable from `xmpp_parsers` and other crates. For that, any code generated by the derive macro mustn't depend on any code in the `xmpp_parsers` crate, because you cannot name the crate you are in portably (`xmpp_parsers::..` wouldn't resolve within `xmpp_parsers`, and `crate::..` would point at other crates if the macro was used in other crates). We also want to interoperate with code already implementing `TryFrom<Element>` and `Into<Element>` on structs. This ultimately requires that we have an error type which is shared by the two implementations and that error type must be declared in the `xso` crate to be usable by the macros. Thus, we port the error type over to use the type declared in `xso`. This changes the structure of the error type greatly; I do not think that `xso` should have to know about all the different types we are parsing there and they don't deserve special treatment. Wrapping them in a `Box<dyn ..>` seems more appropriate.
This commit is contained in:
parent
b3e6e089da
commit
6ef8dbefa3
62 changed files with 916 additions and 892 deletions
|
|
@ -4,10 +4,10 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
use crate::util::error::Error;
|
||||
use base64::{engine::general_purpose::STANDARD as Base64Engine, Engine};
|
||||
use jid::Jid;
|
||||
use std::str::FromStr;
|
||||
use xso::error::Error;
|
||||
|
||||
/// A trait for codecs that can decode and encode text nodes.
|
||||
pub trait Codec {
|
||||
|
|
@ -70,7 +70,7 @@ where
|
|||
match s.trim() {
|
||||
// TODO: This error message can be a bit opaque when used
|
||||
// in-context; ideally it'd be configurable.
|
||||
"" => Err(Error::ParseError(
|
||||
"" => Err(Error::Other(
|
||||
"The text in the element's text node was empty after trimming.",
|
||||
)),
|
||||
trimmed => T::decode(trimmed),
|
||||
|
|
@ -89,7 +89,7 @@ impl Codec for Base64 {
|
|||
type Decoded = Vec<u8>;
|
||||
|
||||
fn decode(s: &str) -> Result<Vec<u8>, Error> {
|
||||
Ok(Base64Engine.decode(s)?)
|
||||
Base64Engine.decode(s).map_err(Error::text_parse_error)
|
||||
}
|
||||
|
||||
fn encode(decoded: &Vec<u8>) -> Option<String> {
|
||||
|
|
@ -109,7 +109,7 @@ impl Codec for WhitespaceAwareBase64 {
|
|||
.filter(|ch| *ch != ' ' && *ch != '\n' && *ch != '\t')
|
||||
.collect();
|
||||
|
||||
Ok(Base64Engine.decode(s)?)
|
||||
Base64Engine.decode(s).map_err(Error::text_parse_error)
|
||||
}
|
||||
|
||||
fn encode(decoded: &Self::Decoded) -> Option<String> {
|
||||
|
|
@ -125,12 +125,13 @@ impl<const N: usize> Codec for FixedHex<N> {
|
|||
|
||||
fn decode(s: &str) -> Result<Self::Decoded, Error> {
|
||||
if s.len() != 2 * N {
|
||||
return Err(Error::ParseError("Invalid length"));
|
||||
return Err(Error::Other("Invalid length"));
|
||||
}
|
||||
|
||||
let mut bytes = [0u8; N];
|
||||
for i in 0..N {
|
||||
bytes[i] = u8::from_str_radix(&s[2 * i..2 * i + 2], 16)?;
|
||||
bytes[i] =
|
||||
u8::from_str_radix(&s[2 * i..2 * i + 2], 16).map_err(Error::text_parse_error)?;
|
||||
}
|
||||
|
||||
Ok(bytes)
|
||||
|
|
@ -154,7 +155,8 @@ impl Codec for ColonSeparatedHex {
|
|||
fn decode(s: &str) -> Result<Self::Decoded, Error> {
|
||||
let mut bytes = vec![];
|
||||
for i in 0..(1 + s.len()) / 3 {
|
||||
let byte = u8::from_str_radix(&s[3 * i..3 * i + 2], 16)?;
|
||||
let byte =
|
||||
u8::from_str_radix(&s[3 * i..3 * i + 2], 16).map_err(Error::text_parse_error)?;
|
||||
if 3 * i + 2 < s.len() {
|
||||
assert_eq!(&s[3 * i + 2..3 * i + 3], ":");
|
||||
}
|
||||
|
|
@ -179,7 +181,7 @@ impl Codec for JidCodec {
|
|||
type Decoded = Jid;
|
||||
|
||||
fn decode(s: &str) -> Result<Jid, Error> {
|
||||
Ok(Jid::from_str(s)?)
|
||||
Jid::from_str(s).map_err(Error::text_parse_error)
|
||||
}
|
||||
|
||||
fn encode(jid: &Jid) -> Option<String> {
|
||||
|
|
@ -205,28 +207,28 @@ mod tests {
|
|||
|
||||
// What if we give it a string that's too long?
|
||||
let err = FixedHex::<3>::decode("01feEF01").unwrap_err();
|
||||
assert_eq!(err.to_string(), "parse error: Invalid length");
|
||||
assert_eq!(err.to_string(), "Invalid length");
|
||||
|
||||
// Too short?
|
||||
let err = FixedHex::<3>::decode("01fe").unwrap_err();
|
||||
assert_eq!(err.to_string(), "parse error: Invalid length");
|
||||
assert_eq!(err.to_string(), "Invalid length");
|
||||
|
||||
// Not-even numbers?
|
||||
let err = FixedHex::<3>::decode("01feE").unwrap_err();
|
||||
assert_eq!(err.to_string(), "parse error: Invalid length");
|
||||
assert_eq!(err.to_string(), "Invalid length");
|
||||
|
||||
// No colon supported.
|
||||
let err = FixedHex::<3>::decode("0:f:EF").unwrap_err();
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
"integer parsing error: invalid digit found in string"
|
||||
"text parse error: invalid digit found in string"
|
||||
);
|
||||
|
||||
// No non-hex character allowed.
|
||||
let err = FixedHex::<3>::decode("01defg").unwrap_err();
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
"integer parsing error: invalid digit found in string"
|
||||
"text parse error: invalid digit found in string"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue