ScanElement: Remove "context: Option<&'a Context>"
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
a25feda90e
commit
b7399dc9a5
3 changed files with 111 additions and 112 deletions
|
@ -8,8 +8,9 @@ description = "Reimplementation of the Scansion project in Rust"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nom = "7.1"
|
nom = "7.1"
|
||||||
jid = "0.9"
|
jid = { version = "0.9", features = [ "minidom" ] }
|
||||||
minidom = "0.15.1"
|
minidom = "0.15.1"
|
||||||
|
xmpp-parsers = "0.19.2"
|
||||||
nom_locate = "4.0.0"
|
nom_locate = "4.0.0"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
|
|
||||||
|
|
201
src/element.rs
201
src/element.rs
|
@ -43,7 +43,8 @@ use crate::parsers::parse_variable;
|
||||||
use crate::types::{Client, Context, Entity, VariableAttr};
|
use crate::types::{Client, Context, Entity, VariableAttr};
|
||||||
|
|
||||||
use jid::BareJid;
|
use jid::BareJid;
|
||||||
use minidom::{Element, Node};
|
use minidom::{Element, Error as MinidomError, Node};
|
||||||
|
use xmpp_parsers::{iq::Iq, message::Message, presence::Presence, Error as XMPPParserError};
|
||||||
|
|
||||||
/// Namespaces used for Client entities
|
/// Namespaces used for Client entities
|
||||||
pub static DEFAULT_NS: &str = "jabber:client";
|
pub static DEFAULT_NS: &str = "jabber:client";
|
||||||
|
@ -66,23 +67,22 @@ enum NodeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct ScanNode<'a> {
|
struct ScanNode {
|
||||||
node: Node,
|
node: Node,
|
||||||
context: Option<&'a Context>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ScanNode<'a> {
|
impl ScanNode {
|
||||||
fn new(node: Node, context: Option<&'a Context>) -> ScanNode {
|
fn new(node: Node) -> ScanNode {
|
||||||
ScanNode { node, context }
|
ScanNode { node }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PartialEq<Node> for ScanNode<'a> {
|
impl PartialEq<Node> for ScanNode {
|
||||||
fn eq(&self, other: &Node) -> bool {
|
fn eq(&self, other: &Node) -> bool {
|
||||||
match (&self.node, other) {
|
match (&self.node, other) {
|
||||||
(Node::Text(text1), Node::Text(text2)) => text1 == text2,
|
(Node::Text(text1), Node::Text(text2)) => text1 == text2,
|
||||||
(Node::Element(elem1), Node::Element(elem2)) => {
|
(Node::Element(elem1), Node::Element(elem2)) => {
|
||||||
ScanElement::new(elem1.clone()).with_context(self.context) == elem2
|
ScanElement::new(elem1.clone()) == *elem2
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
@ -129,30 +129,24 @@ fn filter_whitespace_nodes(nodes: Vec<Node>) -> Vec<Node> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ScanNodes<'a, T: Debug> {
|
struct ScanNodes<T: Debug> {
|
||||||
nodes: Vec<Node>,
|
nodes: Vec<Node>,
|
||||||
context: Option<&'a Context>,
|
|
||||||
_strict: PhantomData<T>,
|
_strict: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ScanNodes<'a, NonStrictComparison> {
|
impl ScanNodes<NonStrictComparison> {
|
||||||
fn new(nodes: Vec<Node>, context: Option<&'a Context>) -> ScanNodes<'a, NonStrictComparison> {
|
fn new(nodes: Vec<Node>) -> ScanNodes<NonStrictComparison> {
|
||||||
Self {
|
Self {
|
||||||
nodes,
|
nodes,
|
||||||
context,
|
|
||||||
_strict: PhantomData,
|
_strict: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ScanNodes<'a, StrictComparison> {
|
impl ScanNodes<StrictComparison> {
|
||||||
fn new_strict(
|
fn new_strict(nodes: Vec<Node>) -> ScanNodes<StrictComparison> {
|
||||||
nodes: Vec<Node>,
|
|
||||||
context: Option<&'a Context>,
|
|
||||||
) -> ScanNodes<'a, StrictComparison> {
|
|
||||||
Self {
|
Self {
|
||||||
nodes,
|
nodes,
|
||||||
context,
|
|
||||||
_strict: PhantomData,
|
_strict: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,11 +155,11 @@ impl<'a> ScanNodes<'a, StrictComparison> {
|
||||||
/// Tags with mixed significant text and children tags aren't valid in XMPP, so we know we can
|
/// Tags with mixed significant text and children tags aren't valid in XMPP, so we know we can
|
||||||
/// remove them. Text leaves are compared as is. When comparing strictly, elements must be exactly the
|
/// remove them. Text leaves are compared as is. When comparing strictly, elements must be exactly the
|
||||||
/// same.
|
/// same.
|
||||||
impl<'a> PartialEq<Vec<Node>> for ScanNodes<'a, StrictComparison> {
|
impl PartialEq<Vec<Node>> for ScanNodes<StrictComparison> {
|
||||||
fn eq(&self, other: &Vec<Node>) -> bool {
|
fn eq(&self, other: &Vec<Node>) -> bool {
|
||||||
let filtered_self = filter_whitespace_nodes(self.nodes.clone())
|
let filtered_self = filter_whitespace_nodes(self.nodes.clone())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|node| ScanNode::new(node, self.context))
|
.map(|node| ScanNode::new(node))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let filtered_other = filter_whitespace_nodes(other.clone());
|
let filtered_other = filter_whitespace_nodes(other.clone());
|
||||||
|
|
||||||
|
@ -176,7 +170,7 @@ impl<'a> PartialEq<Vec<Node>> for ScanNodes<'a, StrictComparison> {
|
||||||
/// Tags with mixed significant text and children tags aren't valid in XMPP, so we know we can
|
/// Tags with mixed significant text and children tags aren't valid in XMPP, so we know we can
|
||||||
/// remove them. Text leaves are compared as is. When doing non-strict comparison, the target
|
/// remove them. Text leaves are compared as is. When doing non-strict comparison, the target
|
||||||
/// element must have all attributes and children of the test element but it can have more.
|
/// element must have all attributes and children of the test element but it can have more.
|
||||||
impl<'a> PartialEq<Vec<Node>> for ScanNodes<'a, NonStrictComparison> {
|
impl PartialEq<Vec<Node>> for ScanNodes<NonStrictComparison> {
|
||||||
fn eq(&self, other: &Vec<Node>) -> bool {
|
fn eq(&self, other: &Vec<Node>) -> bool {
|
||||||
let filtered_other = filter_whitespace_nodes(other.clone());
|
let filtered_other = filter_whitespace_nodes(other.clone());
|
||||||
|
|
||||||
|
@ -184,7 +178,7 @@ impl<'a> PartialEq<Vec<Node>> for ScanNodes<'a, NonStrictComparison> {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
// Maps nodes to their comparison result
|
// Maps nodes to their comparison result
|
||||||
.fold(true, |res, node| {
|
.fold(true, |res, node| {
|
||||||
let scan = ScanNode::new(node, self.context);
|
let scan = ScanNode::new(node);
|
||||||
res && filtered_other
|
res && filtered_other
|
||||||
.iter()
|
.iter()
|
||||||
.find(|onode| &&scan == onode)
|
.find(|onode| &&scan == onode)
|
||||||
|
@ -200,12 +194,11 @@ impl<'a> PartialEq<Vec<Node>> for ScanNodes<'a, NonStrictComparison> {
|
||||||
/// Also uses the custom ScanNode implementation.
|
/// Also uses the custom ScanNode implementation.
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
#[cfg_attr(test, derive(PartialEq))]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ScanElement<'a> {
|
pub struct ScanElement {
|
||||||
elem: Element,
|
pub elem: Element,
|
||||||
context: Option<&'a Context>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Deref for ScanElement<'a> {
|
impl Deref for ScanElement {
|
||||||
type Target = Element;
|
type Target = Element;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
|
@ -213,26 +206,53 @@ impl<'a> Deref for ScanElement<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ScanElement<'a> {
|
fn apply_context(mut elem: Element, context: &Context) -> Element {
|
||||||
pub fn new(elem: Element) -> ScanElement<'a> {
|
// Parse variables in attributes.
|
||||||
Self {
|
for (_attr, val) in elem.attrs_mut() {
|
||||||
elem,
|
if let Ok((_, var)) = parse_variable(val.as_str().into()) {
|
||||||
context: None,
|
match var {
|
||||||
|
VariableAttr::FullJid(name) => match context.get(&name) {
|
||||||
|
Some(Entity::Client(Client { jid, .. })) => *val = String::from(jid.clone()),
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
VariableAttr::BareJid(name) => match context.get(&name) {
|
||||||
|
Some(Entity::Client(Client { jid, .. })) => {
|
||||||
|
*val = String::from(BareJid::from(jid.clone()))
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for node in elem.nodes_mut() {
|
||||||
|
match node {
|
||||||
|
Node::Element(child) => *node = Node::Element(apply_context(child.clone(), context)),
|
||||||
|
Node::Text(text) => *node = Node::Text(text.to_string()),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
elem
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScanElement {
|
||||||
|
pub fn new(elem: Element) -> ScanElement {
|
||||||
|
Self { elem }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply_context(self, context: &Context) -> ScanElement {
|
||||||
|
Self {
|
||||||
|
elem: apply_context(self.elem, context),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_inner(self) -> Element {
|
||||||
|
self.elem
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ScanElement<'a> {
|
impl PartialEq<Element> for ScanElement {
|
||||||
pub fn with_context(self, context: Option<&'a Context>) -> ScanElement<'a> {
|
fn eq(&self, other: &Element) -> bool {
|
||||||
Self {
|
|
||||||
elem: self.elem,
|
|
||||||
context,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> PartialEq<&Element> for ScanElement<'a> {
|
|
||||||
fn eq(&self, other: &&Element) -> bool {
|
|
||||||
let self_ns = self.elem.ns();
|
let self_ns = self.elem.ns();
|
||||||
if self.elem.name() == other.name() && self_ns == other.ns() {
|
if self.elem.name() == other.name() && self_ns == other.ns() {
|
||||||
let strict_attr = self.elem.attr("scansion:strict");
|
let strict_attr = self.elem.attr("scansion:strict");
|
||||||
|
@ -249,28 +269,6 @@ impl<'a> PartialEq<&Element> for ScanElement<'a> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse variables. If parsing fails, continue attr comparison.
|
|
||||||
// If context isn't set, skip this and continue attr comparison.
|
|
||||||
if let Ok((_, var)) = parse_variable(val.into()) &&
|
|
||||||
let Some(context) = self.context {
|
|
||||||
let res = match var {
|
|
||||||
VariableAttr::FullJid(name) => match context.get(&name) {
|
|
||||||
Some(Entity::Client(Client { jid, .. })) => String::from(jid.clone()),
|
|
||||||
_ => return false,
|
|
||||||
},
|
|
||||||
VariableAttr::BareJid(name) => match context.get(&name) {
|
|
||||||
Some(Entity::Client(Client { jid, .. })) => String::from(BareJid::from(jid.clone())),
|
|
||||||
_ => return false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(oval) = other.attr(attr) && res == oval {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match (attr, other.attr(attr)) {
|
match (attr, other.attr(attr)) {
|
||||||
(attr, _) if attr == "scansion:strict" => continue,
|
(attr, _) if attr == "scansion:strict" => continue,
|
||||||
(_, None) => return false,
|
(_, None) => return false,
|
||||||
|
@ -292,11 +290,10 @@ impl<'a> PartialEq<&Element> for ScanElement<'a> {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
let nodes =
|
let nodes = ScanNodes::new_strict(self.elem.nodes().cloned().collect());
|
||||||
ScanNodes::new_strict(self.elem.nodes().cloned().collect(), self.context);
|
|
||||||
nodes == onodes
|
nodes == onodes
|
||||||
} else {
|
} else {
|
||||||
let nodes = ScanNodes::new(self.elem.nodes().cloned().collect(), self.context);
|
let nodes = ScanNodes::new(self.elem.nodes().cloned().collect());
|
||||||
nodes == onodes
|
nodes == onodes
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -320,12 +317,12 @@ mod tests {
|
||||||
let elem1 = Node::Element(Element::from_str("<foo xmlns='bar'/>").unwrap());
|
let elem1 = Node::Element(Element::from_str("<foo xmlns='bar'/>").unwrap());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ScanNodes::new_strict(vec![elem1.clone()], None),
|
ScanNodes::new_strict(vec![elem1.clone()]),
|
||||||
vec![elem1.clone()],
|
vec![elem1.clone()],
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
ScanNodes::new_strict(vec![text1.clone()], None),
|
ScanNodes::new_strict(vec![text1.clone()]),
|
||||||
vec![text2.clone()],
|
vec![text2.clone()],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -337,32 +334,32 @@ mod tests {
|
||||||
let elem1 = Node::Element(Element::from_str("<foo xmlns='bar'/>").unwrap());
|
let elem1 = Node::Element(Element::from_str("<foo xmlns='bar'/>").unwrap());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ScanNodes::new_strict(vec![elem1.clone()], None),
|
ScanNodes::new_strict(vec![elem1.clone()]),
|
||||||
vec![elem1.clone()],
|
vec![elem1.clone()],
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ScanNodes::new_strict(vec![text1.clone(), elem1.clone(), text2.clone()], None),
|
ScanNodes::new_strict(vec![text1.clone(), elem1.clone(), text2.clone()]),
|
||||||
vec![elem1.clone()],
|
vec![elem1.clone()],
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ScanNodes::new_strict(vec![text1.clone(), elem1.clone()], None),
|
ScanNodes::new_strict(vec![text1.clone(), elem1.clone()]),
|
||||||
vec![elem1.clone(), text2.clone()],
|
vec![elem1.clone(), text2.clone()],
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
ScanNodes::new_strict(vec![elem1.clone(), text1.clone(), elem1.clone()], None),
|
ScanNodes::new_strict(vec![elem1.clone(), text1.clone(), elem1.clone()]),
|
||||||
vec![elem1.clone(), elem1.clone()],
|
vec![elem1.clone(), elem1.clone()],
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
ScanNodes::new_strict(vec![elem1.clone(), text1.clone(), elem1.clone()], None),
|
ScanNodes::new_strict(vec![elem1.clone(), text1.clone(), elem1.clone()]),
|
||||||
vec![elem1.clone()],
|
vec![elem1.clone()],
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
ScanNodes::new_strict(vec![Node::Text(String::from("\n\tfoo\n"))], None),
|
ScanNodes::new_strict(vec![Node::Text(String::from("\n\tfoo\n"))]),
|
||||||
vec![Node::Text(String::from("\n\tfoo"))],
|
vec![Node::Text(String::from("\n\tfoo"))],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -375,7 +372,7 @@ mod tests {
|
||||||
let elem2: Element = "<presence xmlns='foo'><foo/></presence>".parse().unwrap();
|
let elem2: Element = "<presence xmlns='foo'><foo/></presence>".parse().unwrap();
|
||||||
let scan1 = ScanElement::new(elem1);
|
let scan1 = ScanElement::new(elem1);
|
||||||
|
|
||||||
assert_eq!(scan1, &elem2);
|
assert_eq!(scan1, elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -388,7 +385,7 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan1 = ScanElement::new(elem1);
|
let scan1 = ScanElement::new(elem1);
|
||||||
|
|
||||||
assert_ne!(scan1, &elem2);
|
assert_ne!(scan1, elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -396,7 +393,7 @@ mod tests {
|
||||||
let elem1: Element = "<presence xmlns='foo'/>".parse().unwrap();
|
let elem1: Element = "<presence xmlns='foo'/>".parse().unwrap();
|
||||||
let scan1 = ScanElement::new(elem1.clone());
|
let scan1 = ScanElement::new(elem1.clone());
|
||||||
|
|
||||||
assert_eq!(scan1, &elem1);
|
assert_eq!(scan1, elem1);
|
||||||
|
|
||||||
let elem2: Element = "<presence scansion:strict='true' xmlns='jabber:client'>
|
let elem2: Element = "<presence scansion:strict='true' xmlns='jabber:client'>
|
||||||
<x xmlns='http://jabber.org/protocol/muc'/>
|
<x xmlns='http://jabber.org/protocol/muc'/>
|
||||||
|
@ -410,7 +407,7 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan2 = ScanElement::new(elem2);
|
let scan2 = ScanElement::new(elem2);
|
||||||
|
|
||||||
assert_eq!(scan2, &elem3);
|
assert_eq!(scan2, elem3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -419,7 +416,7 @@ mod tests {
|
||||||
let elem2: Element = "<presence xmlns='foo'/>".parse().unwrap();
|
let elem2: Element = "<presence xmlns='foo'/>".parse().unwrap();
|
||||||
let scan1 = ScanElement::new(elem1);
|
let scan1 = ScanElement::new(elem1);
|
||||||
|
|
||||||
assert_ne!(scan1, &elem2);
|
assert_ne!(scan1, elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -443,7 +440,7 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan1 = ScanElement::new(elem1);
|
let scan1 = ScanElement::new(elem1);
|
||||||
|
|
||||||
assert_eq!(scan1, &elem2);
|
assert_eq!(scan1, elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -464,7 +461,7 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan1 = ScanElement::new(elem1);
|
let scan1 = ScanElement::new(elem1);
|
||||||
|
|
||||||
assert_ne!(scan1, &elem2);
|
assert_ne!(scan1, elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -474,7 +471,7 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan1 = ScanElement::new(elem1.clone());
|
let scan1 = ScanElement::new(elem1.clone());
|
||||||
|
|
||||||
assert_eq!(scan1, &elem1);
|
assert_eq!(scan1, elem1);
|
||||||
|
|
||||||
let elem2: Element = "<presence xmlns='jabber:client'>
|
let elem2: Element = "<presence xmlns='jabber:client'>
|
||||||
<x xmlns='http://jabber.org/protocol/muc' scansion:strict='false' />
|
<x xmlns='http://jabber.org/protocol/muc' scansion:strict='false' />
|
||||||
|
@ -488,7 +485,7 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan2 = ScanElement::new(elem2);
|
let scan2 = ScanElement::new(elem2);
|
||||||
|
|
||||||
assert_eq!(scan2, &elem3);
|
assert_eq!(scan2, elem3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -499,7 +496,7 @@ mod tests {
|
||||||
let elem2: Element = "<presence xmlns='foo' />".parse().unwrap();
|
let elem2: Element = "<presence xmlns='foo' />".parse().unwrap();
|
||||||
let scan1 = ScanElement::new(elem1);
|
let scan1 = ScanElement::new(elem1);
|
||||||
|
|
||||||
assert_ne!(scan1, &elem2);
|
assert_ne!(scan1, elem2);
|
||||||
|
|
||||||
let elem2: Element = "<presence xmlns='jabber:client' foo='bar'>
|
let elem2: Element = "<presence xmlns='jabber:client' foo='bar'>
|
||||||
<x xmlns='http://jabber.org/protocol/muc'/>
|
<x xmlns='http://jabber.org/protocol/muc'/>
|
||||||
|
@ -513,7 +510,7 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan2 = ScanElement::new(elem2);
|
let scan2 = ScanElement::new(elem2);
|
||||||
|
|
||||||
assert_ne!(scan2, &elem3);
|
assert_ne!(scan2, elem3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -524,7 +521,7 @@ mod tests {
|
||||||
let elem2: Element = "<presence xmlns='foo'><foo/></presence>".parse().unwrap();
|
let elem2: Element = "<presence xmlns='foo'><foo/></presence>".parse().unwrap();
|
||||||
let scan1 = ScanElement::new(elem1);
|
let scan1 = ScanElement::new(elem1);
|
||||||
|
|
||||||
assert_eq!(scan1, &elem2);
|
assert_eq!(scan1, elem2);
|
||||||
|
|
||||||
// 'jabber:client' is non strict by default
|
// 'jabber:client' is non strict by default
|
||||||
let elem3: Element = "<presence xmlns='jabber:client'/>".parse().unwrap();
|
let elem3: Element = "<presence xmlns='jabber:client'/>".parse().unwrap();
|
||||||
|
@ -533,7 +530,7 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan3 = ScanElement::new(elem3);
|
let scan3 = ScanElement::new(elem3);
|
||||||
|
|
||||||
assert_eq!(scan3, &elem4);
|
assert_eq!(scan3, elem4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -550,7 +547,7 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan2 = ScanElement::new(elem2);
|
let scan2 = ScanElement::new(elem2);
|
||||||
|
|
||||||
assert_ne!(scan2, &elem3);
|
assert_ne!(scan2, elem3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -567,7 +564,7 @@ mod tests {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan1 = ScanElement::new(elem1);
|
let scan1 = ScanElement::new(elem1);
|
||||||
|
|
||||||
assert_ne!(scan1, &elem2);
|
assert_ne!(scan1, elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -578,7 +575,7 @@ mod tests {
|
||||||
let elem2: Element = "<message xmlns='foo' id='some-id' />".parse().unwrap();
|
let elem2: Element = "<message xmlns='foo' id='some-id' />".parse().unwrap();
|
||||||
let scan1 = ScanElement::new(elem1);
|
let scan1 = ScanElement::new(elem1);
|
||||||
|
|
||||||
assert_eq!(scan1, &elem2);
|
assert_eq!(scan1, elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -586,12 +583,12 @@ mod tests {
|
||||||
let louise = Client::new(Jid::from_str("louise@example.com").unwrap(), "passwd");
|
let louise = Client::new(Jid::from_str("louise@example.com").unwrap(), "passwd");
|
||||||
let rosa_phone = Client::new(Jid::from_str("rosa@example.com/phone").unwrap(), "passwd");
|
let rosa_phone = Client::new(Jid::from_str("rosa@example.com/phone").unwrap(), "passwd");
|
||||||
|
|
||||||
let context = Some({
|
let context = {
|
||||||
let mut tmp = HashMap::new();
|
let mut tmp = HashMap::new();
|
||||||
tmp.insert(String::from("louise"), Entity::Client(louise));
|
tmp.insert(String::from("louise"), Entity::Client(louise));
|
||||||
tmp.insert(String::from("rosa's phone"), Entity::Client(rosa_phone));
|
tmp.insert(String::from("rosa's phone"), Entity::Client(rosa_phone));
|
||||||
tmp
|
tmp
|
||||||
});
|
};
|
||||||
|
|
||||||
let elem1: Element = "<message xmlns='foo' to=\"${louise's full JID}\" />"
|
let elem1: Element = "<message xmlns='foo' to=\"${louise's full JID}\" />"
|
||||||
.parse()
|
.parse()
|
||||||
|
@ -599,9 +596,9 @@ mod tests {
|
||||||
let elem2: Element = "<message xmlns='foo' to='louise@example.com' />"
|
let elem2: Element = "<message xmlns='foo' to='louise@example.com' />"
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan1 = ScanElement::new(elem1).with_context(context.as_ref());
|
let scan1 = ScanElement::new(elem1).apply_context(&context);
|
||||||
|
|
||||||
assert_eq!(scan1, &elem2);
|
assert_eq!(scan1, elem2);
|
||||||
|
|
||||||
let elem3: Element = "<message xmlns='foo' to=\"${rosa's phone's JID}\" />"
|
let elem3: Element = "<message xmlns='foo' to=\"${rosa's phone's JID}\" />"
|
||||||
.parse()
|
.parse()
|
||||||
|
@ -609,9 +606,9 @@ mod tests {
|
||||||
let elem4: Element = "<message xmlns='foo' to='rosa@example.com' />"
|
let elem4: Element = "<message xmlns='foo' to='rosa@example.com' />"
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan3 = ScanElement::new(elem3).with_context(context.as_ref());
|
let scan3 = ScanElement::new(elem3).apply_context(&context);
|
||||||
|
|
||||||
assert_eq!(scan3, &elem4);
|
assert_eq!(scan3, elem4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -621,11 +618,11 @@ mod tests {
|
||||||
"passwd",
|
"passwd",
|
||||||
);
|
);
|
||||||
|
|
||||||
let context = Some({
|
let context = {
|
||||||
let mut tmp = HashMap::new();
|
let mut tmp = HashMap::new();
|
||||||
tmp.insert(String::from("louise"), Entity::Client(louise));
|
tmp.insert(String::from("louise"), Entity::Client(louise));
|
||||||
tmp
|
tmp
|
||||||
});
|
};
|
||||||
|
|
||||||
let elem1: Element = "<message xmlns='foo'><foo to=\"${louise's full JID}\" /></message>"
|
let elem1: Element = "<message xmlns='foo'><foo to=\"${louise's full JID}\" /></message>"
|
||||||
.parse()
|
.parse()
|
||||||
|
@ -634,8 +631,8 @@ mod tests {
|
||||||
"<message xmlns='foo'><foo to='louise@example.com/device1' /></message>"
|
"<message xmlns='foo'><foo to='louise@example.com/device1' /></message>"
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let scan1 = ScanElement::new(elem1).with_context(context.as_ref());
|
let scan1 = ScanElement::new(elem1).apply_context(&context);
|
||||||
|
|
||||||
assert_eq!(scan1, &elem2);
|
assert_eq!(scan1, elem2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,12 @@ use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
#[cfg_attr(test, derive(PartialEq))]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InOutStanza<'a> {
|
pub struct InOutStanza {
|
||||||
pub inbound: Vec<ScanElement<'a>>,
|
pub inbound: Vec<ScanElement>,
|
||||||
pub outbound: Vec<ScanElement<'a>>,
|
pub outbound: Vec<ScanElement>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> InOutStanza<'a> {
|
impl InOutStanza {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
InOutStanza {
|
InOutStanza {
|
||||||
inbound: Vec::new(),
|
inbound: Vec::new(),
|
||||||
|
@ -35,11 +35,11 @@ impl<'a> InOutStanza<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sends(&mut self, scan: ScanElement<'a>) {
|
fn sends(&mut self, scan: ScanElement) {
|
||||||
self.inbound.push(scan)
|
self.inbound.push(scan)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receives(&mut self, scan: ScanElement<'a>) {
|
fn receives(&mut self, scan: ScanElement) {
|
||||||
self.outbound.push(scan)
|
self.outbound.push(scan)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,8 @@ fn bind_context(context: Context) -> Context {
|
||||||
.collect::<Context>()
|
.collect::<Context>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_actions<'a>(spec: Spec, context: &'a Context) -> Result<InOutStanza<'a>, MinidomError> {
|
/// Reads Actions from Spec and converts that to InOutStanza
|
||||||
|
pub fn read_actions(spec: Spec, context: &Context) -> Result<InOutStanza, MinidomError> {
|
||||||
let mut inout = InOutStanza::new();
|
let mut inout = InOutStanza::new();
|
||||||
for action in spec.actions {
|
for action in spec.actions {
|
||||||
match action {
|
match action {
|
||||||
|
@ -174,10 +175,10 @@ louise receives:
|
||||||
let context: Context = bind_context(spec.context.clone());
|
let context: Context = bind_context(spec.context.clone());
|
||||||
let res = InOutStanza {
|
let res = InOutStanza {
|
||||||
inbound: vec![
|
inbound: vec![
|
||||||
ScanElement::new(JOIN.parse::<Element>().unwrap()).with_context(Some(&context))
|
ScanElement::new(JOIN.parse::<Element>().unwrap()).apply_context(&context)
|
||||||
],
|
],
|
||||||
outbound: vec![
|
outbound: vec![
|
||||||
ScanElement::new(CONFIRM.parse::<Element>().unwrap()).with_context(Some(&context))
|
ScanElement::new(CONFIRM.parse::<Element>().unwrap()).apply_context(&context)
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue