Introduce comparing with namespace support.
This commit is contained in:
parent
04ec34bed8
commit
1b1661fd82
16 changed files with 156 additions and 20 deletions
|
|
@ -38,7 +38,8 @@ impl TryFrom<Element> for ChatState {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
|
|
||||||
fn try_from(elem: Element) -> Result<ChatState, Error> {
|
fn try_from(elem: Element) -> Result<ChatState, Error> {
|
||||||
if elem.ns() != Some(ns::CHATSTATES) {
|
let ns = elem.ns();
|
||||||
|
if ns.as_ref().map(|ns| ns.as_str()) != Some(ns::CHATSTATES) {
|
||||||
return Err(Error::ParseError("This is not a chatstate element."));
|
return Err(Error::ParseError("This is not a chatstate element."));
|
||||||
}
|
}
|
||||||
for _ in elem.children() {
|
for _ in elem.children() {
|
||||||
|
|
|
||||||
118
src/compare_elements.rs
Normal file
118
src/compare_elements.rs
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
use minidom::{Node, Element};
|
||||||
|
|
||||||
|
pub trait NamespaceAwareCompare {
|
||||||
|
/// Namespace-aware comparison for tests
|
||||||
|
fn compare_to(&self, other: &Self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NamespaceAwareCompare for Node {
|
||||||
|
fn compare_to(&self, other: &Self) -> bool {
|
||||||
|
match (self, other) {
|
||||||
|
(&Node::Element(ref elem1), &Node::Element(ref elem2)) =>
|
||||||
|
Element::compare_to(elem1, elem2),
|
||||||
|
(&Node::Text(ref text1), &Node::Text(ref text2)) =>
|
||||||
|
text1 == text2,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NamespaceAwareCompare for Element {
|
||||||
|
fn compare_to(&self, other: &Self) -> bool {
|
||||||
|
if self.name() == other.name() &&
|
||||||
|
self.ns() == other.ns() &&
|
||||||
|
self.attrs().eq(other.attrs())
|
||||||
|
{
|
||||||
|
let child_elems = self.children().count();
|
||||||
|
let text_is_whitespace = self.texts()
|
||||||
|
.all(|text| text.chars().all(char::is_whitespace));
|
||||||
|
if child_elems > 0 && text_is_whitespace {
|
||||||
|
// Ignore all the whitespace text nodes
|
||||||
|
self.children().zip(other.children())
|
||||||
|
.all(|(node1, node2)| node1.compare_to(node2))
|
||||||
|
} else {
|
||||||
|
// Compare with text nodes
|
||||||
|
self.nodes().zip(other.nodes())
|
||||||
|
.all(|(node1, node2)| node1.compare_to(node2))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use minidom::Element;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simple() {
|
||||||
|
let elem1: Element = "<a a='b'>x <l/> 3</a>".parse().unwrap();
|
||||||
|
let elem2: Element = "<a a='b'>x <l/> 3</a>".parse().unwrap();
|
||||||
|
assert!(elem1.compare_to(&elem2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn wrong_attr_name() {
|
||||||
|
let elem1: Element = "<a a='b'>x 3</a>".parse().unwrap();
|
||||||
|
let elem2: Element = "<a c='b'>x 3</a>".parse().unwrap();
|
||||||
|
assert!(!elem1.compare_to(&elem2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn wrong_attr_value() {
|
||||||
|
let elem1: Element = "<a a='b'>x 3</a>".parse().unwrap();
|
||||||
|
let elem2: Element = "<a a='c'>x 3</a>".parse().unwrap();
|
||||||
|
assert!(!elem1.compare_to(&elem2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn attr_order() {
|
||||||
|
let elem1: Element = "<e1 a='b' c='d'/>".parse().unwrap();
|
||||||
|
let elem2: Element = "<e1 c='d' a='b'/>".parse().unwrap();
|
||||||
|
assert!(elem1.compare_to(&elem2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn wrong_texts() {
|
||||||
|
let elem1: Element = "<e1>foo</e1>".parse().unwrap();
|
||||||
|
let elem2: Element = "<e1>bar</e1>".parse().unwrap();
|
||||||
|
assert!(!elem1.compare_to(&elem2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn children() {
|
||||||
|
let elem1: Element = "<e1><foo/><bar/></e1>".parse().unwrap();
|
||||||
|
let elem2: Element = "<e1><foo/><bar/></e1>".parse().unwrap();
|
||||||
|
assert!(elem1.compare_to(&elem2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn wrong_children() {
|
||||||
|
let elem1: Element = "<e1><foo/></e1>".parse().unwrap();
|
||||||
|
let elem2: Element = "<e1><bar/></e1>".parse().unwrap();
|
||||||
|
assert!(!elem1.compare_to(&elem2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn xmlns_wrong() {
|
||||||
|
let elem1: Element = "<e1 xmlns='ns1'><foo/></e1>".parse().unwrap();
|
||||||
|
let elem2: Element = "<e1 xmlns='ns2'><foo/></e1>".parse().unwrap();
|
||||||
|
assert!(!elem1.compare_to(&elem2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn xmlns_other_prefix() {
|
||||||
|
let elem1: Element = "<e1 xmlns='ns1'><foo/></e1>".parse().unwrap();
|
||||||
|
let elem2: Element = "<x:e1 xmlns:x='ns1'><x:foo/></x:e1>".parse().unwrap();
|
||||||
|
assert!(elem1.compare_to(&elem2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn xmlns_dup() {
|
||||||
|
let elem1: Element = "<e1 xmlns='ns1'><foo/></e1>".parse().unwrap();
|
||||||
|
let elem2: Element = "<e1 xmlns='ns1'><foo xmlns='ns1'/></e1>".parse().unwrap();
|
||||||
|
assert!(elem1.compare_to(&elem2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -370,6 +370,7 @@ impl From<DiscoItemsResult> for Element {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use compare_elements::NamespaceAwareCompare;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -394,7 +395,7 @@ mod tests {
|
||||||
assert_eq!(query.extensions[0].form_type, Some(String::from("example")));
|
assert_eq!(query.extensions[0].form_type, Some(String::from("example")));
|
||||||
|
|
||||||
let elem2 = query.into();
|
let elem2 = query.into();
|
||||||
assert_eq!(elem1, elem2);
|
assert!(elem1.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ impl From<Query> for Element {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use compare_elements::NamespaceAwareCompare;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple() {
|
fn test_simple() {
|
||||||
|
|
@ -157,7 +158,7 @@ mod tests {
|
||||||
assert!(form.fields.binary_search_by(|field| field.var.cmp(&String::from("x-gender"))).is_ok());
|
assert!(form.fields.binary_search_by(|field| field.var.cmp(&String::from("x-gender"))).is_ok());
|
||||||
assert!(form.fields.binary_search_by(|field| field.var.cmp(&String::from("coucou"))).is_err());
|
assert!(form.fields.binary_search_by(|field| field.var.cmp(&String::from("coucou"))).is_err());
|
||||||
let elem2 = query.into();
|
let elem2 = query.into();
|
||||||
assert_eq!(elem1, elem2);
|
assert!(elem1.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -190,6 +191,6 @@ mod tests {
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
let elem2 = query.into();
|
let elem2 = query.into();
|
||||||
assert_eq!(elem1, elem2);
|
assert!(elem1.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,7 @@ impl From<Iq> for Element {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use stanza_error::{ErrorType, DefinedCondition};
|
use stanza_error::{ErrorType, DefinedCondition};
|
||||||
|
use compare_elements::NamespaceAwareCompare;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_require_type() {
|
fn test_require_type() {
|
||||||
|
|
@ -328,7 +329,7 @@ mod tests {
|
||||||
assert_eq!(iq.to, None);
|
assert_eq!(iq.to, None);
|
||||||
assert_eq!(iq.id, None);
|
assert_eq!(iq.id, None);
|
||||||
assert!(match iq.payload {
|
assert!(match iq.payload {
|
||||||
IqType::Get(element) => element == query,
|
IqType::Get(element) => element.compare_to(&query),
|
||||||
_ => false
|
_ => false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -349,7 +350,7 @@ mod tests {
|
||||||
assert_eq!(iq.to, None);
|
assert_eq!(iq.to, None);
|
||||||
assert_eq!(iq.id, None);
|
assert_eq!(iq.id, None);
|
||||||
assert!(match iq.payload {
|
assert!(match iq.payload {
|
||||||
IqType::Set(element) => element == vcard,
|
IqType::Set(element) => element.compare_to(&vcard),
|
||||||
_ => false
|
_ => false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -386,7 +387,7 @@ mod tests {
|
||||||
assert_eq!(iq.to, None);
|
assert_eq!(iq.to, None);
|
||||||
assert_eq!(iq.id, None);
|
assert_eq!(iq.id, None);
|
||||||
assert!(match iq.payload {
|
assert!(match iq.payload {
|
||||||
IqType::Result(Some(element)) => element == query,
|
IqType::Result(Some(element)) => element.compare_to(&query),
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,8 @@ impl TryFrom<Element> for ReasonElement {
|
||||||
let mut reason = None;
|
let mut reason = None;
|
||||||
let mut text = None;
|
let mut text = None;
|
||||||
for child in elem.children() {
|
for child in elem.children() {
|
||||||
if child.ns() != Some(ns::JINGLE) {
|
let child_ns = child.ns();
|
||||||
|
if child_ns.as_ref().map(|ns| ns.as_str()) != Some(ns::JINGLE) {
|
||||||
return Err(Error::ParseError("Reason contains a foreign element."));
|
return Err(Error::ParseError("Reason contains a foreign element."));
|
||||||
}
|
}
|
||||||
match child.name() {
|
match child.name() {
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,8 @@ impl TryFrom<Element> for JingleMI {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
|
|
||||||
fn try_from(elem: Element) -> Result<JingleMI, Error> {
|
fn try_from(elem: Element) -> Result<JingleMI, Error> {
|
||||||
if elem.ns() != Some(ns::JINGLE_MESSAGE) {
|
let ns = elem.ns();
|
||||||
|
if ns.as_ref().map(|ns| ns.as_str()) != Some(ns::JINGLE_MESSAGE) {
|
||||||
return Err(Error::ParseError("This is not a Jingle message element."));
|
return Err(Error::ParseError("This is not a Jingle message element."));
|
||||||
}
|
}
|
||||||
Ok(match elem.name() {
|
Ok(match elem.name() {
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,7 @@ impl From<Transport> for Element {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use compare_elements::NamespaceAwareCompare;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple() {
|
fn test_simple() {
|
||||||
|
|
@ -205,7 +206,7 @@ mod tests {
|
||||||
payload: TransportPayload::Activated(String::from("coucou")),
|
payload: TransportPayload::Activated(String::from("coucou")),
|
||||||
};
|
};
|
||||||
let elem2: Element = transport.into();
|
let elem2: Element = transport.into();
|
||||||
assert_eq!(elem, elem2);
|
assert!(elem.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -225,6 +226,6 @@ mod tests {
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
let elem2: Element = transport.into();
|
let elem2: Element = transport.into();
|
||||||
assert_eq!(elem, elem2);
|
assert!(elem.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,10 @@ pub mod error;
|
||||||
/// XML namespace definitions used through XMPP.
|
/// XML namespace definitions used through XMPP.
|
||||||
pub mod ns;
|
pub mod ns;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
/// Namespace-aware comparison for tests
|
||||||
|
mod compare_elements;
|
||||||
|
|
||||||
/// RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core
|
/// RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core
|
||||||
pub mod message;
|
pub mod message;
|
||||||
/// RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core
|
/// RFC 6120: Extensible Messaging and Presence Protocol (XMPP): Core
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,7 @@ impl From<Message> for Element {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use compare_elements::NamespaceAwareCompare;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple() {
|
fn test_simple() {
|
||||||
|
|
@ -281,7 +282,7 @@ mod tests {
|
||||||
assert_eq!(message.bodies[""], Body::from_str("Hello world!").unwrap());
|
assert_eq!(message.bodies[""], Body::from_str("Hello world!").unwrap());
|
||||||
|
|
||||||
let elem2 = message.into();
|
let elem2 = message.into();
|
||||||
assert_eq!(elem1, elem2);
|
assert!(elem1.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -293,7 +294,7 @@ mod tests {
|
||||||
let mut message = Message::new(Some(Jid::from_str("coucou@example.org").unwrap()));
|
let mut message = Message::new(Some(Jid::from_str("coucou@example.org").unwrap()));
|
||||||
message.bodies.insert(String::from(""), Body::from_str("Hello world!").unwrap());
|
message.bodies.insert(String::from(""), Body::from_str("Hello world!").unwrap());
|
||||||
let elem2 = message.into();
|
let elem2 = message.into();
|
||||||
assert_eq!(elem, elem2);
|
assert!(elem.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -307,7 +308,7 @@ mod tests {
|
||||||
assert_eq!(message.subjects[""], Subject::from_str("Hello world!").unwrap());
|
assert_eq!(message.subjects[""], Subject::from_str("Hello world!").unwrap());
|
||||||
|
|
||||||
let elem2 = message.into();
|
let elem2 = message.into();
|
||||||
assert_eq!(elem1, elem2);
|
assert!(elem1.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -387,6 +387,7 @@ impl From<MucUser> for Element {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
|
use compare_elements::NamespaceAwareCompare;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple() {
|
fn test_simple() {
|
||||||
|
|
@ -418,7 +419,7 @@ mod tests {
|
||||||
".parse().unwrap();
|
".parse().unwrap();
|
||||||
let muc = MucUser { status: vec!(), items: vec!() };
|
let muc = MucUser { status: vec!(), items: vec!() };
|
||||||
let elem2 = muc.into();
|
let elem2 = muc.into();
|
||||||
assert_eq!(elem, elem2);
|
assert!(elem.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,7 @@ impl From<Presence> for Element {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use compare_elements::NamespaceAwareCompare;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple() {
|
fn test_simple() {
|
||||||
|
|
@ -363,7 +364,7 @@ mod tests {
|
||||||
let elem: Element = "<presence xmlns='jabber:component:accept' type='unavailable'/>/>".parse().unwrap();
|
let elem: Element = "<presence xmlns='jabber:component:accept' type='unavailable'/>/>".parse().unwrap();
|
||||||
let presence = Presence::new(Type::Unavailable);
|
let presence = Presence::new(Type::Unavailable);
|
||||||
let elem2 = presence.into();
|
let elem2 = presence.into();
|
||||||
assert_eq!(elem, elem2);
|
assert!(elem.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -272,6 +272,7 @@ impl From<PubSubEvent> for Element {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use compare_elements::NamespaceAwareCompare;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple() {
|
fn test_simple() {
|
||||||
|
|
@ -417,6 +418,6 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
let elem2: Element = event.into();
|
let elem2: Element = event.into();
|
||||||
assert_eq!(elem, elem2);
|
assert!(elem.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ impl From<Roster> for Element {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use compare_elements::NamespaceAwareCompare;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get() {
|
fn test_get() {
|
||||||
|
|
@ -206,7 +207,7 @@ mod tests {
|
||||||
assert_eq!(roster.items[0].groups[0], Group::from_str("A").unwrap());
|
assert_eq!(roster.items[0].groups[0], Group::from_str("A").unwrap());
|
||||||
assert_eq!(roster.items[0].groups[1], Group::from_str("B").unwrap());
|
assert_eq!(roster.items[0].groups[1], Group::from_str("B").unwrap());
|
||||||
let elem2 = roster.into();
|
let elem2 = roster.into();
|
||||||
assert_eq!(elem1, elem2);
|
assert!(elem1.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,7 @@ impl From<Set> for Element {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use compare_elements::NamespaceAwareCompare;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple() {
|
fn test_simple() {
|
||||||
|
|
@ -197,6 +198,6 @@ mod tests {
|
||||||
max: None,
|
max: None,
|
||||||
};
|
};
|
||||||
let elem2 = set2.into();
|
let elem2 = set2.into();
|
||||||
assert_eq!(elem1, elem2);
|
assert!(elem1.compare_to(&elem2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@ impl TryFrom<Element> for StanzaError {
|
||||||
let mut other = None;
|
let mut other = None;
|
||||||
|
|
||||||
for child in elem.children() {
|
for child in elem.children() {
|
||||||
|
let child_ns = child.ns();
|
||||||
if child.is("text", ns::XMPP_STANZAS) {
|
if child.is("text", ns::XMPP_STANZAS) {
|
||||||
for _ in child.children() {
|
for _ in child.children() {
|
||||||
return Err(Error::ParseError("Unknown element in error text."));
|
return Err(Error::ParseError("Unknown element in error text."));
|
||||||
|
|
@ -144,7 +145,7 @@ impl TryFrom<Element> for StanzaError {
|
||||||
if texts.insert(lang, child.text()).is_some() {
|
if texts.insert(lang, child.text()).is_some() {
|
||||||
return Err(Error::ParseError("Text element present twice for the same xml:lang."));
|
return Err(Error::ParseError("Text element present twice for the same xml:lang."));
|
||||||
}
|
}
|
||||||
} else if child.ns() == Some(ns::XMPP_STANZAS) {
|
} else if child_ns.as_ref().map(|ns| ns.as_str()) == Some(ns::XMPP_STANZAS) {
|
||||||
if defined_condition.is_some() {
|
if defined_condition.is_some() {
|
||||||
return Err(Error::ParseError("Error must not have more than one defined-condition."));
|
return Err(Error::ParseError("Error must not have more than one defined-condition."));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue