From a104ebc3f6ec8183e21e2ecf08f95e5767791dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20=E2=80=9Cpep=E2=80=9D=20Buquet?= Date: Wed, 23 Oct 2019 01:32:41 +0200 Subject: [PATCH] Rustfmt pass, and rustfmt --check in CI" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime “pep” Buquet --- .gitlab-ci.yml | 6 + jid-rs/src/lib.rs | 50 ++-- minidom-rs/src/convert.rs | 36 ++- minidom-rs/src/element.rs | 175 +++++++------ minidom-rs/src/error.rs | 13 +- minidom-rs/src/lib.rs | 13 +- minidom-rs/src/namespace_set.rs | 43 ++-- minidom-rs/src/node.rs | 8 +- minidom-rs/src/tests.rs | 125 +++++---- tokio-xmpp/examples/contact_addr.rs | 39 ++- tokio-xmpp/examples/download_avatars.rs | 69 +++-- tokio-xmpp/examples/echo_bot.rs | 11 +- tokio-xmpp/examples/echo_component.rs | 2 +- tokio-xmpp/src/client/auth.rs | 108 ++++---- tokio-xmpp/src/client/bind.rs | 2 +- tokio-xmpp/src/client/mod.rs | 15 +- tokio-xmpp/src/component/mod.rs | 2 +- tokio-xmpp/src/error.rs | 10 +- tokio-xmpp/src/happy_eyeballs.rs | 3 +- tokio-xmpp/src/starttls.rs | 2 +- tokio-xmpp/src/stream_start.rs | 2 +- tokio-xmpp/src/xmpp_codec.rs | 30 +-- tokio-xmpp/src/xmpp_stream.rs | 2 +- xmpp-parsers/examples/generate-caps.rs | 8 +- xmpp-parsers/src/bind.rs | 35 ++- xmpp-parsers/src/blocking.rs | 4 +- xmpp-parsers/src/bob.rs | 41 ++- xmpp-parsers/src/bookmarks2.rs | 12 +- xmpp-parsers/src/caps.rs | 4 +- xmpp-parsers/src/cert_management.rs | 34 ++- xmpp-parsers/src/chatstates.rs | 2 +- xmpp-parsers/src/csi.rs | 14 +- xmpp-parsers/src/data_forms.rs | 16 +- xmpp-parsers/src/delay.rs | 4 +- xmpp-parsers/src/disco.rs | 27 +- xmpp-parsers/src/ecaps2.rs | 12 +- xmpp-parsers/src/hashes.rs | 10 +- xmpp-parsers/src/ibb.rs | 4 +- xmpp-parsers/src/ibr.rs | 4 +- xmpp-parsers/src/idle.rs | 2 +- xmpp-parsers/src/iq.rs | 18 +- xmpp-parsers/src/jid_prep.rs | 19 +- xmpp-parsers/src/jingle.rs | 36 ++- xmpp-parsers/src/jingle_dtls_srtp.rs | 18 +- xmpp-parsers/src/jingle_ft.rs | 31 ++- xmpp-parsers/src/jingle_ibb.rs | 2 +- xmpp-parsers/src/jingle_ice_udp.rs | 12 +- xmpp-parsers/src/jingle_message.rs | 2 +- xmpp-parsers/src/jingle_rtcp_fb.rs | 3 +- xmpp-parsers/src/jingle_rtp.rs | 7 +- xmpp-parsers/src/jingle_s5b.rs | 12 +- xmpp-parsers/src/jingle_ssma.rs | 9 +- xmpp-parsers/src/lib.rs | 4 +- xmpp-parsers/src/mam.rs | 16 +- xmpp-parsers/src/media_element.rs | 2 +- xmpp-parsers/src/message.rs | 58 ++--- xmpp-parsers/src/muc/muc.rs | 2 +- xmpp-parsers/src/muc/user.rs | 12 +- xmpp-parsers/src/occupant_id.rs | 4 +- xmpp-parsers/src/openpgp.rs | 27 +- xmpp-parsers/src/presence.rs | 63 ++--- xmpp-parsers/src/pubsub/event.rs | 20 +- xmpp-parsers/src/pubsub/mod.rs | 8 +- xmpp-parsers/src/pubsub/pubsub.rs | 6 +- xmpp-parsers/src/receipts.rs | 2 +- xmpp-parsers/src/roster.rs | 2 +- xmpp-parsers/src/rsm.rs | 13 +- xmpp-parsers/src/sasl.rs | 19 +- xmpp-parsers/src/stanza_error.rs | 30 ++- xmpp-parsers/src/stanza_id.rs | 2 +- xmpp-parsers/src/time.rs | 24 +- xmpp-parsers/src/tune.rs | 42 ++- xmpp-parsers/src/util/helpers.rs | 5 +- xmpp-parsers/src/util/macros.rs | 41 +-- xmpp-parsers/src/xhtml.rs | 326 +++++++++++++++++------- xmpp-rs/examples/hello_bot.rs | 32 ++- xmpp-rs/src/lib.rs | 308 ++++++++++++---------- xmpp-rs/src/pubsub/avatar.rs | 23 +- xmpp-rs/src/pubsub/mod.rs | 42 +-- 79 files changed, 1344 insertions(+), 957 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dabc9688ae0ea505f4e0dba09c2753003b0e5184..03d7c4c52c26683a39bf585881d894217c6ec28b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,5 @@ stages: + - lint - build - test @@ -30,6 +31,11 @@ variables: script: - cargo test --verbose +rustfmt: + stage: lint + script: + - rustfmt --check --edition 2018 **/*.rs + rust-latest-build: extends: - .build diff --git a/jid-rs/src/lib.rs b/jid-rs/src/lib.rs index ec56a71ecd626d839c8b5efb72cdfbe1c022355c..9f8ecd3aecca1f0c8fe0330ffac1b39364893a2c 100644 --- a/jid-rs/src/lib.rs +++ b/jid-rs/src/lib.rs @@ -40,12 +40,16 @@ impl StdError for JidParseError {} impl fmt::Display for JidParseError { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{}", match self { - JidParseError::NoDomain => "no domain found in this JID", - JidParseError::NoResource => "no resource found in this full JID", - JidParseError::EmptyNode => "nodepart empty despite the presence of a @", - JidParseError::EmptyResource => "resource empty despite the presence of a /", - }) + write!( + fmt, + "{}", + match self { + JidParseError::NoDomain => "no domain found in this JID", + JidParseError::NoResource => "no resource found in this full JID", + JidParseError::EmptyNode => "nodepart empty despite the presence of a @", + JidParseError::EmptyResource => "resource empty despite the presence of a /", + } + ) } } @@ -623,8 +627,8 @@ impl Into for BareJid { mod tests { use super::*; - use std::str::FromStr; use std::collections::HashMap; + use std::str::FromStr; #[test] fn can_parse_full_jids() { @@ -710,22 +714,13 @@ mod tests { let full = FullJid::new("a", "b.c", "d"); let bare = BareJid::new("a", "b.c"); - assert_eq!( - FullJid::try_from(Jid::Full(full.clone())), - Ok(full.clone()), - ); + assert_eq!(FullJid::try_from(Jid::Full(full.clone())), Ok(full.clone()),); assert_eq!( FullJid::try_from(Jid::Bare(bare.clone())), Err(JidParseError::NoResource), ); - assert_eq!( - BareJid::from(Jid::Full(full.clone())), - bare.clone(), - ); - assert_eq!( - BareJid::from(Jid::Bare(bare.clone())), - bare, - ); + assert_eq!(BareJid::from(Jid::Full(full.clone())), bare.clone(),); + assert_eq!(BareJid::from(Jid::Bare(bare.clone())), bare,); } #[test] @@ -760,10 +755,19 @@ mod tests { #[test] fn display_jids() { - assert_eq!(format!("{}", FullJid::new("a", "b", "c")), String::from("a@b/c")); - assert_eq!(format!("{}", BareJid::new("a", "b")), String::from("a@b")); - assert_eq!(format!("{}", Jid::Full(FullJid::new("a", "b", "c"))), String::from("a@b/c")); - assert_eq!(format!("{}", Jid::Bare(BareJid::new("a", "b"))), String::from("a@b")); + assert_eq!( + format!("{}", FullJid::new("a", "b", "c")), + String::from("a@b/c") + ); + assert_eq!(format!("{}", BareJid::new("a", "b")), String::from("a@b")); + assert_eq!( + format!("{}", Jid::Full(FullJid::new("a", "b", "c"))), + String::from("a@b/c") + ); + assert_eq!( + format!("{}", Jid::Bare(BareJid::new("a", "b"))), + String::from("a@b") + ); } #[cfg(feature = "minidom")] diff --git a/minidom-rs/src/convert.rs b/minidom-rs/src/convert.rs index 7c6d314e56df62c13a3c6c9e62c6491859a14c54..0898a1393442317342c63de0564defde26123e55 100644 --- a/minidom-rs/src/convert.rs +++ b/minidom-rs/src/convert.rs @@ -13,7 +13,7 @@ macro_rules! impl_into_attribute_value { Some(format!("{}", self)) } } - } + }; } macro_rules! impl_into_attribute_values { @@ -22,7 +22,19 @@ macro_rules! impl_into_attribute_values { } } -impl_into_attribute_values!(usize, u64, u32, u16, u8, isize, i64, i32, i16, i8, ::std::net::IpAddr); +impl_into_attribute_values!( + usize, + u64, + u32, + u16, + u8, + isize, + i64, + i32, + i16, + i8, + ::std::net::IpAddr +); impl IntoAttributeValue for String { fn into_attribute_value(self) -> Option { @@ -56,14 +68,20 @@ mod tests { #[test] fn test_into_attribute_value_on_ints() { - assert_eq!(16u8.into_attribute_value().unwrap() , "16"); - assert_eq!(17u16.into_attribute_value().unwrap() , "17"); - assert_eq!(18u32.into_attribute_value().unwrap() , "18"); - assert_eq!(19u64.into_attribute_value().unwrap() , "19"); - assert_eq!( 16i8.into_attribute_value().unwrap() , "16"); + assert_eq!(16u8.into_attribute_value().unwrap(), "16"); + assert_eq!(17u16.into_attribute_value().unwrap(), "17"); + assert_eq!(18u32.into_attribute_value().unwrap(), "18"); + assert_eq!(19u64.into_attribute_value().unwrap(), "19"); + assert_eq!(16i8.into_attribute_value().unwrap(), "16"); assert_eq!((-17i16).into_attribute_value().unwrap(), "-17"); - assert_eq!( 18i32.into_attribute_value().unwrap(), "18"); + assert_eq!(18i32.into_attribute_value().unwrap(), "18"); assert_eq!((-19i64).into_attribute_value().unwrap(), "-19"); - assert_eq!(IpAddr::from_str("127.000.0.1").unwrap().into_attribute_value().unwrap(), "127.0.0.1"); + assert_eq!( + IpAddr::from_str("127.000.0.1") + .unwrap() + .into_attribute_value() + .unwrap(), + "127.0.0.1" + ); } } diff --git a/minidom-rs/src/element.rs b/minidom-rs/src/element.rs index 08ccc709ecad30354909a673d5eefd9321c349a8..199c620ef2c0d7596b3513998200988268a3ba0e 100644 --- a/minidom-rs/src/element.rs +++ b/minidom-rs/src/element.rs @@ -5,16 +5,16 @@ use crate::error::{Error, Result}; use crate::namespace_set::NamespaceSet; use crate::node::Node; -use std::io:: Write; use std::collections::{btree_map, BTreeMap}; +use std::io::Write; -use std::str; -use std::rc::Rc; use std::borrow::Cow; +use std::rc::Rc; +use std::str; +use quick_xml::events::{BytesDecl, BytesEnd, BytesStart, Event}; use quick_xml::Reader as EventReader; use quick_xml::Writer as EventWriter; -use quick_xml::events::{Event, BytesStart, BytesEnd, BytesDecl}; use std::io::BufRead; @@ -68,7 +68,6 @@ pub fn escape(raw: &[u8]) -> Cow<[u8]> { } } - #[derive(Clone, PartialEq, Eq, Debug)] /// A struct representing a DOM Element. pub struct Element { @@ -97,9 +96,16 @@ impl FromStr for Element { } impl Element { - fn new>(name: String, prefix: Option, namespaces: NS, attributes: BTreeMap, children: Vec) -> Element { + fn new>( + name: String, + prefix: Option, + namespaces: NS, + attributes: BTreeMap, + children: Vec, + ) -> Element { Element { - prefix, name, + prefix, + name, namespaces: Rc::new(namespaces.into()), attributes, children, @@ -186,7 +192,7 @@ impl Element { /// Returns a reference to the value of the given attribute, if it exists, else `None`. pub fn attr(&self, name: &str) -> Option<&str> { if let Some(value) = self.attributes.get(name) { - return Some(value) + return Some(value); } None } @@ -225,7 +231,8 @@ impl Element { let val = val.into_attribute_value(); if let Some(value) = self.attributes.get_mut(&name) { - *value = val.expect("removing existing value via set_attr, this is not yet supported (TODO)"); // TODO + *value = val + .expect("removing existing value via set_attr, this is not yet supported (TODO)"); // TODO return; } @@ -249,8 +256,7 @@ impl Element { /// assert_eq!(elem.is("wrong", "wrong"), false); /// ``` pub fn is, NS: AsRef>(&self, name: N, namespace: NS) -> bool { - self.name == name.as_ref() && - self.has_ns(namespace) + self.name == name.as_ref() && self.has_ns(namespace) } /// Returns whether the element has the given namespace. @@ -278,22 +284,22 @@ impl Element { match e { Event::Empty(ref e) | Event::Start(ref e) => { break build_element(reader, e)?; - }, + } Event::Eof => { return Err(Error::EndOfDocument); - }, + } #[cfg(not(feature = "comments"))] Event::Comment { .. } => { return Err(Error::CommentsDisabled); } #[cfg(feature = "comments")] Event::Comment { .. } => (), - Event::Text { .. } | - Event::End { .. } | - Event::CData { .. } | - Event::Decl { .. } | - Event::PI { .. } | - Event::DocType { .. } => (), // TODO: may need more errors + Event::Text { .. } + | Event::End { .. } + | Event::CData { .. } + | Event::Decl { .. } + | Event::PI { .. } + | Event::DocType { .. } => (), // TODO: may need more errors } }; @@ -305,11 +311,11 @@ impl Element { let elem = build_element(reader, e)?; // Since there is no Event::End after, directly append it to the current node stack.last_mut().unwrap().append_child(elem); - }, + } Event::Start(ref e) => { let elem = build_element(reader, e)?; stack.push(elem); - }, + } Event::End(ref e) => { if stack.len() <= 1 { break; @@ -327,15 +333,15 @@ impl Element { if possible_prefix != prefix.as_bytes() { return Err(Error::InvalidElementClosed); } - }, + } None => { return Err(Error::InvalidElementClosed); - }, + } } if name != elem.name().as_bytes() { return Err(Error::InvalidElementClosed); } - }, + } None => { if elem.prefix().is_some() { return Err(Error::InvalidElementClosed); @@ -343,28 +349,28 @@ impl Element { if possible_prefix != elem.name().as_bytes() { return Err(Error::InvalidElementClosed); } - }, + } } to.append_child(elem); } - }, + } Event::Text(s) => { let text = s.unescape_and_decode(reader)?; if text != "" { let current_elem = stack.last_mut().unwrap(); current_elem.append_text_node(text); } - }, + } Event::CData(s) => { let text = reader.decode(&s)?.to_owned(); if text != "" { let current_elem = stack.last_mut().unwrap(); current_elem.append_text_node(text); } - }, + } Event::Eof => { break; - }, + } #[cfg(not(feature = "comments"))] Event::Comment(_) => return Err(Error::CommentsDisabled), #[cfg(feature = "comments")] @@ -374,10 +380,8 @@ impl Element { let current_elem = stack.last_mut().unwrap(); current_elem.append_comment_node(comment); } - }, - Event::Decl { .. } | - Event::PI { .. } | - Event::DocType { .. } => (), + } + Event::Decl { .. } | Event::PI { .. } | Event::DocType { .. } => (), } } Ok(stack.pop().unwrap()) @@ -408,7 +412,7 @@ impl Element { Some(ref prefix) => { let key = format!("xmlns:{}", prefix); start.push_attribute((key.as_bytes(), ns.as_bytes())) - }, + } } } for (key, value) in &self.attributes { @@ -417,7 +421,7 @@ impl Element { if self.children.is_empty() { writer.write_event(Event::Empty(start))?; - return Ok(()) + return Ok(()); } writer.write_event(Event::Start(start))?; @@ -448,12 +452,14 @@ impl Element { /// assert_eq!(iter.next().unwrap().as_text().unwrap(), "c"); /// assert_eq!(iter.next(), None); /// ``` - #[inline] pub fn nodes(&self) -> Nodes { + #[inline] + pub fn nodes(&self) -> Nodes { self.children.iter() } /// Returns an iterator over mutable references to every child node of this element. - #[inline] pub fn nodes_mut(&mut self) -> NodesMut { + #[inline] + pub fn nodes_mut(&mut self) -> NodesMut { self.children.iter_mut() } @@ -472,14 +478,16 @@ impl Element { /// assert_eq!(iter.next().unwrap().name(), "child3"); /// assert_eq!(iter.next(), None); /// ``` - #[inline] pub fn children(&self) -> Children { + #[inline] + pub fn children(&self) -> Children { Children { iter: self.children.iter(), } } /// Returns an iterator over mutable references to every child element of this element. - #[inline] pub fn children_mut(&mut self) -> ChildrenMut { + #[inline] + pub fn children_mut(&mut self) -> ChildrenMut { ChildrenMut { iter: self.children.iter_mut(), } @@ -499,14 +507,16 @@ impl Element { /// assert_eq!(iter.next().unwrap(), " world!"); /// assert_eq!(iter.next(), None); /// ``` - #[inline] pub fn texts(&self) -> Texts { + #[inline] + pub fn texts(&self) -> Texts { Texts { iter: self.children.iter(), } } /// Returns an iterator over mutable references to every text node of this element. - #[inline] pub fn texts_mut(&mut self) -> TextsMut { + #[inline] + pub fn texts_mut(&mut self) -> TextsMut { TextsMut { iter: self.children.iter_mut(), } @@ -630,7 +640,11 @@ impl Element { /// assert_eq!(elem.get_child("b", "other_ns"), None); /// assert_eq!(elem.get_child("a", "inexistent_ns"), None); /// ``` - pub fn get_child, NS: AsRef>(&self, name: N, namespace: NS) -> Option<&Element> { + pub fn get_child, NS: AsRef>( + &self, + name: N, + namespace: NS, + ) -> Option<&Element> { for fork in &self.children { if let Node::Element(ref e) = *fork { if e.is(name.as_ref(), namespace.as_ref()) { @@ -643,7 +657,11 @@ impl Element { /// Returns a mutable reference to the first child element with the specific name and namespace, /// if it exists in the direct descendants of this `Element`, else returns `None`. - pub fn get_child_mut, NS: AsRef>(&mut self, name: N, namespace: NS) -> Option<&mut Element> { + pub fn get_child_mut, NS: AsRef>( + &mut self, + name: N, + namespace: NS, + ) -> Option<&mut Element> { for fork in &mut self.children { if let Node::Element(ref mut e) = *fork { if e.is(name.as_ref(), namespace.as_ref()) { @@ -690,7 +708,11 @@ impl Element { /// assert!(elem.remove_child("a", "ns").is_none()); /// assert!(elem.remove_child("inexistent", "inexistent").is_none()); /// ``` - pub fn remove_child, NS: AsRef>(&mut self, name: N, namespace: NS) -> Option { + pub fn remove_child, NS: AsRef>( + &mut self, + name: N, + namespace: NS, + ) -> Option { let name = name.as_ref(); let namespace = namespace.as_ref(); let idx = self.children.iter().position(|x| { @@ -715,25 +737,24 @@ fn split_element_name>(s: S) -> Result<(Option, String)> { fn build_element(reader: &EventReader, event: &BytesStart) -> Result { let mut namespaces = BTreeMap::new(); - let attributes = event.attributes() + let attributes = event + .attributes() .map(|o| { let o = o?; let key = str::from_utf8(o.key)?.to_owned(); let value = o.unescape_and_decode_value(reader)?; Ok((key, value)) }) - .filter(|o| { - match *o { - Ok((ref key, ref value)) if key == "xmlns" => { - namespaces.insert(None, value.to_owned()); - false - }, - Ok((ref key, ref value)) if key.starts_with("xmlns:") => { - namespaces.insert(Some(key[6..].to_owned()), value.to_owned()); - false - }, - _ => true, + .filter(|o| match *o { + Ok((ref key, ref value)) if key == "xmlns" => { + namespaces.insert(None, value.to_owned()); + false + } + Ok((ref key, ref value)) if key.starts_with("xmlns:") => { + namespaces.insert(Some(key[6..].to_owned()), value.to_owned()); + false } + _ => true, }) .collect::>>()?; @@ -861,7 +882,11 @@ impl ElementBuilder { } /// Sets an attribute. - pub fn attr, V: IntoAttributeValue>(mut self, name: S, value: V) -> ElementBuilder { + pub fn attr, V: IntoAttributeValue>( + mut self, + name: S, + value: V, + ) -> ElementBuilder { self.root.set_attr(name, value); self } @@ -873,7 +898,10 @@ impl ElementBuilder { } /// Appends an iterator of things implementing `Into` into the tree. - pub fn append_all, I: IntoIterator>(mut self, iter: I) -> ElementBuilder { + pub fn append_all, I: IntoIterator>( + mut self, + iter: I, + ) -> ElementBuilder { for node in iter { self.root.append_node(node.into()); } @@ -903,11 +931,13 @@ mod tests { fn test_element_new() { use std::iter::FromIterator; - let elem = Element::new( "name".to_owned() - , None - , Some("namespace".to_owned()) - , BTreeMap::from_iter(vec![ ("name".to_string(), "value".to_string()) ].into_iter() ) - , Vec::new() ); + let elem = Element::new( + "name".to_owned(), + None, + Some("namespace".to_owned()), + BTreeMap::from_iter(vec![("name".to_string(), "value".to_string())].into_iter()), + Vec::new(), + ); assert_eq!(elem.name(), "name"); assert_eq!(elem.ns(), Some("namespace".to_owned())); @@ -932,12 +962,8 @@ mod tests { let mut reader = EventReader::from_str(xml); let elem = Element::from_reader(&mut reader); - let nested = Element::builder("bar") - .attr("baz", "qxx") - .build(); - let elem2 = Element::builder("foo") - .append(nested) - .build(); + let nested = Element::builder("bar").attr("baz", "qxx").build(); + let elem2 = Element::builder("foo").append(nested).build(); assert_eq!(elem.unwrap(), elem2); } @@ -948,18 +974,15 @@ mod tests { let mut reader = EventReader::from_str(xml); let elem = Element::from_reader(&mut reader); - let nested = Element::builder("prefix:bar") - .attr("baz", "qxx") - .build(); - let elem2 = Element::builder("foo") - .append(nested) - .build(); + let nested = Element::builder("prefix:bar").attr("baz", "qxx").build(); + let elem2 = Element::builder("foo").append(nested).build(); assert_eq!(elem.unwrap(), elem2); } #[test] - fn parses_spectest_xml() { // From: https://gitlab.com/lumi/minidom-rs/issues/8 + fn parses_spectest_xml() { + // From: https://gitlab.com/lumi/minidom-rs/issues/8 let xml = r#" diff --git a/minidom-rs/src/error.rs b/minidom-rs/src/error.rs index 579cee405aca8c68af1aa1f97dd0ff02329774df..7f9f33aad4540d75fffa50446a9926a990ab5703 100644 --- a/minidom-rs/src/error.rs +++ b/minidom-rs/src/error.rs @@ -52,11 +52,18 @@ impl std::fmt::Display for Error { Error::XmlError(e) => write!(fmt, "XML error: {}", e), Error::Utf8Error(e) => write!(fmt, "UTF-8 error: {}", e), Error::IoError(e) => write!(fmt, "IO error: {}", e), - Error::EndOfDocument => write!(fmt, "the end of the document has been reached prematurely"), - Error::InvalidElementClosed => write!(fmt, "the XML is invalid, an element was wrongly closed"), + Error::EndOfDocument => { + write!(fmt, "the end of the document has been reached prematurely") + } + Error::InvalidElementClosed => { + write!(fmt, "the XML is invalid, an element was wrongly closed") + } Error::InvalidElement => write!(fmt, "the XML element is invalid"), #[cfg(not(comments))] - Error::CommentsDisabled => write!(fmt, "a comment has been found even though comments are disabled by feature"), + Error::CommentsDisabled => write!( + fmt, + "a comment has been found even though comments are disabled by feature" + ), } } } diff --git a/minidom-rs/src/lib.rs b/minidom-rs/src/lib.rs index c7f43b23010d693ef3df8a92e2969cb8c608aa41..2fd9901007af4a46b929461b30c70ee282624e36 100644 --- a/minidom-rs/src/lib.rs +++ b/minidom-rs/src/lib.rs @@ -66,15 +66,16 @@ pub use quick_xml; -pub mod error; -pub mod element; pub mod convert; -pub mod node; +pub mod element; +pub mod error; mod namespace_set; +pub mod node; -#[cfg(test)] mod tests; +#[cfg(test)] +mod tests; +pub use convert::IntoAttributeValue; +pub use element::{Children, ChildrenMut, Element, ElementBuilder}; pub use error::{Error, Result}; -pub use element::{Element, Children, ChildrenMut, ElementBuilder}; pub use node::Node; -pub use convert::IntoAttributeValue; diff --git a/minidom-rs/src/namespace_set.rs b/minidom-rs/src/namespace_set.rs index 163a87304aadb1320e4ff4731f2a8f66614d97d6..857336fe40103a285ed4b238fff73f13fc99d95b 100644 --- a/minidom-rs/src/namespace_set.rs +++ b/minidom-rs/src/namespace_set.rs @@ -1,9 +1,8 @@ -use std::collections::BTreeMap; use std::cell::RefCell; +use std::collections::BTreeMap; use std::fmt; use std::rc::Rc; - #[derive(Clone, PartialEq, Eq)] pub struct NamespaceSet { parent: RefCell>>, @@ -23,10 +22,15 @@ impl fmt::Debug for NamespaceSet { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "NamespaceSet(")?; for (prefix, namespace) in &self.namespaces { - write!(f, "xmlns{}={:?}, ", match prefix { - None => String::new(), - Some(prefix) => format!(":{}", prefix), - }, namespace)?; + write!( + f, + "xmlns{}={:?}, ", + match prefix { + None => String::new(), + Some(prefix) => format!(":{}", prefix), + }, + namespace + )?; } write!(f, "parent: {:?})", *self.parent.borrow()) } @@ -42,20 +46,17 @@ impl NamespaceSet { Some(ns) => Some(ns.clone()), None => match *self.parent.borrow() { None => None, - Some(ref parent) => parent.get(prefix) + Some(ref parent) => parent.get(prefix), }, } } pub fn has>(&self, prefix: &Option, wanted_ns: NS) -> bool { match self.namespaces.get(prefix) { - Some(ns) => - ns == wanted_ns.as_ref(), + Some(ns) => ns == wanted_ns.as_ref(), None => match *self.parent.borrow() { - None => - false, - Some(ref parent) => - parent.has(prefix, wanted_ns), + None => false, + Some(ref parent) => parent.has(prefix, wanted_ns), }, } } @@ -65,7 +66,6 @@ impl NamespaceSet { let new_set = parent; *parent_ns = Some(new_set); } - } impl From, String>> for NamespaceSet { @@ -132,7 +132,10 @@ mod tests { #[test] fn get_has_prefixed() { let namespaces = NamespaceSet::from(("x".to_owned(), "bar".to_owned())); - assert_eq!(namespaces.get(&Some("x".to_owned())), Some("bar".to_owned())); + assert_eq!( + namespaces.get(&Some("x".to_owned())), + Some("bar".to_owned()) + ); assert!(namespaces.has(&Some("x".to_owned()), "bar")); } @@ -154,7 +157,10 @@ mod tests { for _ in 0..1000 { let namespaces = NamespaceSet::default(); namespaces.set_parent(Rc::new(parent)); - assert_eq!(namespaces.get(&Some("x".to_owned())), Some("bar".to_owned())); + assert_eq!( + namespaces.get(&Some("x".to_owned())), + Some("bar".to_owned()) + ); assert!(namespaces.has(&Some("x".to_owned()), "bar")); parent = namespaces; } @@ -163,7 +169,10 @@ mod tests { #[test] fn debug_looks_correct() { let parent = NamespaceSet::from("http://www.w3.org/2000/svg".to_owned()); - let namespaces = NamespaceSet::from(("xhtml".to_owned(), "http://www.w3.org/1999/xhtml".to_owned())); + let namespaces = NamespaceSet::from(( + "xhtml".to_owned(), + "http://www.w3.org/1999/xhtml".to_owned(), + )); namespaces.set_parent(Rc::new(parent)); assert_eq!(format!("{:?}", namespaces), "NamespaceSet(xmlns:xhtml=\"http://www.w3.org/1999/xhtml\", parent: Some(NamespaceSet(xmlns=\"http://www.w3.org/2000/svg\", parent: None)))"); } diff --git a/minidom-rs/src/node.rs b/minidom-rs/src/node.rs index e0d9a9ebbcf5dd3c2d68a879664491b042c07568..ebce9063f4710db486203e715ccf6b972cccbfc0 100644 --- a/minidom-rs/src/node.rs +++ b/minidom-rs/src/node.rs @@ -5,8 +5,8 @@ use crate::error::Result; use std::io::Write; +use quick_xml::events::{BytesText, Event}; use quick_xml::Writer as EventWriter; -use quick_xml::events::{Event, BytesText}; /// A node in an element tree. #[derive(Clone, Debug, PartialEq, Eq)] @@ -166,16 +166,16 @@ impl Node { } #[doc(hidden)] - pub(crate) fn write_to_inner(&self, writer: &mut EventWriter) -> Result<()>{ + pub(crate) fn write_to_inner(&self, writer: &mut EventWriter) -> Result<()> { match *self { Node::Element(ref elmt) => elmt.write_to_inner(writer)?, Node::Text(ref s) => { writer.write_event(Event::Text(BytesText::from_plain_str(s)))?; - }, + } #[cfg(feature = "comments")] Node::Comment(ref s) => { writer.write_event(Event::Comment(BytesText::from_plain_str(s)))?; - }, + } } Ok(()) diff --git a/minidom-rs/src/tests.rs b/minidom-rs/src/tests.rs index 046d8e5c817ac79febb208709c4f96b7671f8297..22e257aa04dd6a17192d795e05b72cdb78e4406d 100644 --- a/minidom-rs/src/tests.rs +++ b/minidom-rs/src/tests.rs @@ -6,20 +6,18 @@ const TEST_STRING: &'static str = r#" Element { let mut root = Element::builder("root") - .ns("root_ns") - .attr("xml:lang", "en") - .attr("a", "b") - .build(); + .ns("root_ns") + .attr("xml:lang", "en") + .attr("a", "b") + .build(); root.append_text_node("meow"); - let child = Element::builder("child") - .attr("c", "d") - .build(); + let child = Element::builder("child").attr("c", "d").build(); root.append_child(child); let other_child = Element::builder("child") - .ns("child_ns") - .attr("d", "e") - .attr("xml:lang", "fr") - .build(); + .ns("child_ns") + .attr("d", "e") + .attr("xml:lang", "fr") + .build(); root.append_child(other_child); root.append_text_node("nya"); root @@ -43,7 +41,10 @@ fn build_comment_test_tree() -> Element { #[test] fn reader_works() { let mut reader = Reader::from_str(TEST_STRING); - assert_eq!(Element::from_reader(&mut reader).unwrap(), build_test_tree()); + assert_eq!( + Element::from_reader(&mut reader).unwrap(), + build_test_tree() + ); } #[test] @@ -58,40 +59,38 @@ fn writer_works() { #[test] fn writer_escapes_attributes() { - let root = Element::builder("root") - .attr("a", "\"Air\" quotes") - .build(); + let root = Element::builder("root").attr("a", "\"Air\" quotes").build(); let mut writer = Vec::new(); { root.write_to(&mut writer).unwrap(); } - assert_eq!(String::from_utf8(writer).unwrap(), - r#""# + assert_eq!( + String::from_utf8(writer).unwrap(), + r#""# ); } #[test] fn writer_escapes_text() { - let root = Element::builder("root") - .append("<3") - .build(); + let root = Element::builder("root").append("<3").build(); let mut writer = Vec::new(); { root.write_to(&mut writer).unwrap(); } - assert_eq!(String::from_utf8(writer).unwrap(), - r#"<3"# + assert_eq!( + String::from_utf8(writer).unwrap(), + r#"<3"# ); } #[test] fn builder_works() { let elem = Element::builder("a") - .ns("b") - .attr("c", "d") - .append(Element::builder("child")) - .append("e") - .build(); + .ns("b") + .attr("c", "d") + .append(Element::builder("child")) + .append("e") + .build(); assert_eq!(elem.name(), "a"); assert_eq!(elem.ns(), Some("b".to_owned())); assert_eq!(elem.attr("c"), Some("d")); @@ -115,10 +114,22 @@ fn get_child_works() { let root = build_test_tree(); assert_eq!(root.get_child("child", "inexistent_ns"), None); assert_eq!(root.get_child("not_a_child", "root_ns"), None); - assert!(root.get_child("child", "root_ns").unwrap().is("child", "root_ns")); - assert!(root.get_child("child", "child_ns").unwrap().is("child", "child_ns")); - assert_eq!(root.get_child("child", "root_ns").unwrap().attr("c"), Some("d")); - assert_eq!(root.get_child("child", "child_ns").unwrap().attr("d"), Some("e")); + assert!(root + .get_child("child", "root_ns") + .unwrap() + .is("child", "root_ns")); + assert!(root + .get_child("child", "child_ns") + .unwrap() + .is("child", "child_ns")); + assert_eq!( + root.get_child("child", "root_ns").unwrap().attr("c"), + Some("d") + ); + assert_eq!( + root.get_child("child", "child_ns").unwrap().attr("d"), + Some("e") + ); } #[test] @@ -130,9 +141,14 @@ fn namespace_propagation_works() { root.append_child(child); assert_eq!(root.get_child("child", "root_ns").unwrap().ns(), root.ns()); - assert_eq!(root.get_child("child", "root_ns").unwrap() - .get_child("grandchild", "root_ns").unwrap() - .ns(), root.ns()); + assert_eq!( + root.get_child("child", "root_ns") + .unwrap() + .get_child("grandchild", "root_ns") + .unwrap() + .ns(), + root.ns() + ); } #[test] @@ -151,7 +167,13 @@ fn namespace_attributes_works() { let mut reader = Reader::from_str(TEST_STRING); let root = Element::from_reader(&mut reader).unwrap(); assert_eq!("en", root.attr("xml:lang").unwrap()); - assert_eq!("fr", root.get_child("child", "child_ns").unwrap().attr("xml:lang").unwrap()); + assert_eq!( + "fr", + root.get_child("child", "child_ns") + .unwrap() + .attr("xml:lang") + .unwrap() + ); } #[test] @@ -174,14 +196,20 @@ fn namespace_simple() { #[test] fn namespace_prefixed() { let elem: Element = "" - .parse().unwrap(); + .parse() + .unwrap(); assert_eq!(elem.name(), "features"); - assert_eq!(elem.ns(), Some("http://etherx.jabber.org/streams".to_owned())); + assert_eq!( + elem.ns(), + Some("http://etherx.jabber.org/streams".to_owned()) + ); } #[test] fn namespace_inherited_simple() { - let elem: Element = "".parse().unwrap(); + let elem: Element = "" + .parse() + .unwrap(); assert_eq!(elem.name(), "stream"); assert_eq!(elem.ns(), Some("jabber:client".to_owned())); let child = elem.children().next().unwrap(); @@ -194,7 +222,10 @@ fn namespace_inherited_prefixed1() { let elem: Element = "" .parse().unwrap(); assert_eq!(elem.name(), "features"); - assert_eq!(elem.ns(), Some("http://etherx.jabber.org/streams".to_owned())); + assert_eq!( + elem.ns(), + Some("http://etherx.jabber.org/streams".to_owned()) + ); let child = elem.children().next().unwrap(); assert_eq!(child.name(), "message"); assert_eq!(child.ns(), Some("jabber:client".to_owned())); @@ -205,7 +236,10 @@ fn namespace_inherited_prefixed2() { let elem: Element = "" .parse().unwrap(); assert_eq!(elem.name(), "stream"); - assert_eq!(elem.ns(), Some("http://etherx.jabber.org/streams".to_owned())); + assert_eq!( + elem.ns(), + Some("http://etherx.jabber.org/streams".to_owned()) + ); let child = elem.children().next().unwrap(); assert_eq!(child.name(), "message"); assert_eq!(child.ns(), Some("jabber:client".to_owned())); @@ -215,7 +249,10 @@ fn namespace_inherited_prefixed2() { #[test] fn read_comments() { let mut reader = Reader::from_str(COMMENT_TEST_STRING); - assert_eq!(Element::from_reader(&mut reader).unwrap(), build_comment_test_tree()); + assert_eq!( + Element::from_reader(&mut reader).unwrap(), + build_comment_test_tree() + ); } #[cfg(feature = "comments")] @@ -233,12 +270,12 @@ fn write_comments() { fn xml_error() { match "".parse::() { Err(crate::error::Error::XmlError(_)) => (), - err => panic!("No or wrong error: {:?}", err) + err => panic!("No or wrong error: {:?}", err), } match "() { Err(crate::error::Error::XmlError(_)) => (), - err => panic!("No or wrong error: {:?}", err) + err => panic!("No or wrong error: {:?}", err), } } @@ -246,6 +283,6 @@ fn xml_error() { fn invalid_element_error() { match "".parse::() { Err(crate::error::Error::InvalidElement) => (), - err => panic!("No or wrong error: {:?}", err) + err => panic!("No or wrong error: {:?}", err), } } diff --git a/tokio-xmpp/examples/contact_addr.rs b/tokio-xmpp/examples/contact_addr.rs index f60601a8cdacad09d2b0a5577e89e8d6591b0b4b..e3148437b2708d2ac8ce0cd983f2ec1729fb21de 100644 --- a/tokio-xmpp/examples/contact_addr.rs +++ b/tokio-xmpp/examples/contact_addr.rs @@ -3,20 +3,13 @@ use std::convert::TryFrom; use std::env::args; use std::process::exit; use tokio::runtime::current_thread::Runtime; -use tokio_xmpp::{Client, xmpp_codec::Packet}; +use tokio_xmpp::{xmpp_codec::Packet, Client}; use xmpp_parsers::{ - Element, - Jid, + disco::{DiscoInfoQuery, DiscoInfoResult}, + iq::{Iq, IqType}, ns, - iq::{ - Iq, - IqType, - }, - disco::{ - DiscoInfoResult, - DiscoInfoQuery, - }, server_info::ServerInfo, + Element, Jid, }; fn main() { @@ -95,17 +88,19 @@ fn make_disco_iq(target: Jid) -> Element { } fn convert_field(field: Vec) -> String { - field.iter() - .fold((field.len(), String::new()), |(l, mut acc), s| { - acc.push('<'); - acc.push_str(&s); - acc.push('>'); - if l > 1 { - acc.push(','); - acc.push(' '); - } - (0, acc) - }).1 + field + .iter() + .fold((field.len(), String::new()), |(l, mut acc), s| { + acc.push('<'); + acc.push_str(&s); + acc.push('>'); + if l > 1 { + acc.push(','); + acc.push(' '); + } + (0, acc) + }) + .1 } fn print_server_info(server_info: ServerInfo) { diff --git a/tokio-xmpp/examples/download_avatars.rs b/tokio-xmpp/examples/download_avatars.rs index ec27b6e5a9ad97285735a4409179aea22d50d2a6..ec4222d2d7e5f23877701cc99e8980003c2af2e0 100644 --- a/tokio-xmpp/examples/download_avatars.rs +++ b/tokio-xmpp/examples/download_avatars.rs @@ -21,7 +21,7 @@ use xmpp_parsers::{ pubsub::{Items, PubSub}, NodeName, }, - stanza_error::{StanzaError, ErrorType, DefinedCondition}, + stanza_error::{DefinedCondition, ErrorType, StanzaError}, Jid, }; @@ -46,16 +46,14 @@ fn main() { // Create outgoing pipe let (mut tx, rx) = futures::unsync::mpsc::unbounded(); rt.spawn( - rx.forward( - sink.sink_map_err(|_| panic!("Pipe")) - ) + rx.forward(sink.sink_map_err(|_| panic!("Pipe"))) .map(|(rx, mut sink)| { drop(rx); let _ = sink.close(); }) .map_err(|e| { panic!("Send error: {:?}", e); - }) + }), ); let disco_info = make_disco(); @@ -66,8 +64,7 @@ fn main() { // Helper function to send an iq error. let mut send_error = |to, id, type_, condition, text: &str| { let error = StanzaError::new(type_, condition, "en", text); - let iq = Iq::from_error(id, error) - .with_to(to); + let iq = Iq::from_error(id, error).with_to(to); tx.start_send(Packet::Stanza(iq.into())).unwrap(); }; @@ -89,28 +86,45 @@ fn main() { Ok(query) => { let mut disco = disco_info.clone(); disco.node = query.node; - let iq = Iq::from_result(iq.id, Some(disco)) - .with_to(iq.from.unwrap()); + let iq = + Iq::from_result(iq.id, Some(disco)).with_to(iq.from.unwrap()); tx.start_send(Packet::Stanza(iq.into())).unwrap(); - }, + } Err(err) => { - send_error(iq.from.unwrap(), iq.id, ErrorType::Modify, DefinedCondition::BadRequest, &format!("{}", err)); - }, + send_error( + iq.from.unwrap(), + iq.id, + ErrorType::Modify, + DefinedCondition::BadRequest, + &format!("{}", err), + ); + } } } else { // We MUST answer unhandled get iqs with a service-unavailable error. - send_error(iq.from.unwrap(), iq.id, ErrorType::Cancel, DefinedCondition::ServiceUnavailable, "No handler defined for this kind of iq."); + send_error( + iq.from.unwrap(), + iq.id, + ErrorType::Cancel, + DefinedCondition::ServiceUnavailable, + "No handler defined for this kind of iq.", + ); } } else if let IqType::Result(Some(payload)) = iq.payload { if payload.is("pubsub", ns::PUBSUB) { let pubsub = PubSub::try_from(payload).unwrap(); - let from = - iq.from.clone().unwrap_or(Jid::from_str(jid).unwrap()); + let from = iq.from.clone().unwrap_or(Jid::from_str(jid).unwrap()); handle_iq_result(pubsub, &from); } } else if let IqType::Set(_) = iq.payload { // We MUST answer unhandled set iqs with a service-unavailable error. - send_error(iq.from.unwrap(), iq.id, ErrorType::Cancel, DefinedCondition::ServiceUnavailable, "No handler defined for this kind of iq."); + send_error( + iq.from.unwrap(), + iq.id, + ErrorType::Cancel, + DefinedCondition::ServiceUnavailable, + "No handler defined for this kind of iq.", + ); } } else if stanza.is("message", "jabber:client") { let message = Message::try_from(stanza).unwrap(); @@ -186,20 +200,22 @@ fn get_disco_caps(disco: &DiscoInfoResult, node: &str) -> Caps { // Construct a fn make_presence(caps: Caps) -> Presence { - let mut presence = Presence::new(PresenceType::None) - .with_priority(-1); + let mut presence = Presence::new(PresenceType::None).with_priority(-1); presence.set_status("en", "Downloading avatars."); presence.add_payload(caps); presence } fn download_avatar(from: Jid) -> Iq { - Iq::from_get("coucou", PubSub::Items(Items { - max_items: None, - node: NodeName(String::from(ns::AVATAR_DATA)), - subid: None, - items: Vec::new(), - })) + Iq::from_get( + "coucou", + PubSub::Items(Items { + max_items: None, + node: NodeName(String::from(ns::AVATAR_DATA)), + subid: None, + items: Vec::new(), + }), + ) .with_to(from) } @@ -222,10 +238,7 @@ fn handle_iq_result(pubsub: PubSub, from: &Jid) { fn save_avatar(from: &Jid, id: String, data: &[u8]) -> io::Result<()> { let directory = format!("data/{}", from); let filename = format!("data/{}/{}", from, id); - println!( - "Saving avatar from {} to {}.", - from, filename - ); + println!("Saving avatar from {} to {}.", from, filename); create_dir_all(directory)?; let mut file = File::create(filename)?; file.write_all(data) diff --git a/tokio-xmpp/examples/echo_bot.rs b/tokio-xmpp/examples/echo_bot.rs index a4144bf4f695475fc174bdc735867fd9a19a41c0..3fcd9aa7c7a115c53a4094137f1b320b117e5f16 100644 --- a/tokio-xmpp/examples/echo_bot.rs +++ b/tokio-xmpp/examples/echo_bot.rs @@ -4,9 +4,9 @@ use std::env::args; use std::process::exit; use tokio::runtime::current_thread::Runtime; use tokio_xmpp::{Client, Packet}; -use xmpp_parsers::{Jid, Element}; use xmpp_parsers::message::{Body, Message, MessageType}; use xmpp_parsers::presence::{Presence, Show as PresenceShow, Type as PresenceType}; +use xmpp_parsers::{Element, Jid}; fn main() { let args: Vec = args().collect(); @@ -29,16 +29,14 @@ fn main() { // Create outgoing pipe let (mut tx, rx) = futures::unsync::mpsc::unbounded(); rt.spawn( - rx.forward( - sink.sink_map_err(|_| panic!("Pipe")) - ) + rx.forward(sink.sink_map_err(|_| panic!("Pipe"))) .map(|(rx, mut sink)| { drop(rx); let _ = sink.close(); }) .map_err(|e| { panic!("Send error: {:?}", e); - }) + }), ); // Main loop, processes events @@ -47,7 +45,8 @@ fn main() { if wait_for_stream_end { /* Do nothing */ } else if event.is_online() { - let jid = event.get_jid() + let jid = event + .get_jid() .map(|jid| format!("{}", jid)) .unwrap_or("unknown".to_owned()); println!("Online at {}", jid); diff --git a/tokio-xmpp/examples/echo_component.rs b/tokio-xmpp/examples/echo_component.rs index 6a8bc33c8fbd09ca93e0bac20516de5eda72975c..29218ffe14cde3afd986f894103ba7d2f3add4c4 100644 --- a/tokio-xmpp/examples/echo_component.rs +++ b/tokio-xmpp/examples/echo_component.rs @@ -5,9 +5,9 @@ use std::process::exit; use std::str::FromStr; use tokio::runtime::current_thread::Runtime; use tokio_xmpp::Component; -use xmpp_parsers::{Jid, Element}; use xmpp_parsers::message::{Body, Message, MessageType}; use xmpp_parsers::presence::{Presence, Show as PresenceShow, Type as PresenceType}; +use xmpp_parsers::{Element, Jid}; fn main() { let args: Vec = args().collect(); diff --git a/tokio-xmpp/src/client/auth.rs b/tokio-xmpp/src/client/auth.rs index 096a0bfbca3070dea65c31942c55fc5d8dce2e99..ca62845508af9bc13ca257172d0b707f39cd8630 100644 --- a/tokio-xmpp/src/client/auth.rs +++ b/tokio-xmpp/src/client/auth.rs @@ -1,11 +1,14 @@ -use std::str::FromStr; -use std::collections::HashSet; -use std::convert::TryFrom; -use futures::{Future, Poll, Stream, future::{ok, err, IntoFuture}}; +use futures::{ + future::{err, ok, IntoFuture}, + Future, Poll, Stream, +}; use sasl::client::mechanisms::{Anonymous, Plain, Scram}; use sasl::client::Mechanism; use sasl::common::scram::{Sha1, Sha256}; use sasl::common::Credentials; +use std::collections::HashSet; +use std::convert::TryFrom; +use std::str::FromStr; use tokio_io::{AsyncRead, AsyncWrite}; use xmpp_parsers::sasl::{Auth, Challenge, Failure, Mechanism as XMPPMechanism, Response, Success}; @@ -41,67 +44,74 @@ impl ClientAuth { let mut mechanism = local_mech(); if remote_mechs.contains(mechanism.name()) { let initial = mechanism.initial().map_err(AuthError::Sasl)?; - let mechanism_name = XMPPMechanism::from_str(mechanism.name()).map_err(ProtocolError::Parsers)?; + let mechanism_name = + XMPPMechanism::from_str(mechanism.name()).map_err(ProtocolError::Parsers)?; let send_initial = Box::new(stream.send_stanza(Auth { mechanism: mechanism_name, data: initial, })) - .map_err(Error::Io); - let future = Box::new(send_initial.and_then( - |stream| Self::handle_challenge(stream, mechanism) - ).and_then( - |stream| stream.restart() - )); - return Ok(ClientAuth { - future, - }); + .map_err(Error::Io); + let future = Box::new( + send_initial + .and_then(|stream| Self::handle_challenge(stream, mechanism)) + .and_then(|stream| stream.restart()), + ); + return Ok(ClientAuth { future }); } } Err(AuthError::NoMechanism)? } - fn handle_challenge(stream: XMPPStream, mut mechanism: Box) -> Box, Error = Error>> { + fn handle_challenge( + stream: XMPPStream, + mut mechanism: Box, + ) -> Box, Error = Error>> { Box::new( - stream.into_future() - .map_err(|(e, _stream)| e.into()) - .and_then(|(stanza, stream)| { - match stanza { - Some(Packet::Stanza(stanza)) => { - if let Ok(challenge) = Challenge::try_from(stanza.clone()) { - let response = mechanism - .response(&challenge.data); - Box::new( - response - .map_err(|e| AuthError::Sasl(e).into()) - .into_future() - .and_then(|response| { - // Send response and loop - stream.send_stanza(Response { data: response }) - .map_err(Error::Io) - .and_then(|stream| Self::handle_challenge(stream, mechanism)) - }) - ) - } else if let Ok(_) = Success::try_from(stanza.clone()) { - Box::new(ok(stream)) - } else if let Ok(failure) = Failure::try_from(stanza.clone()) { - Box::new(err(Error::Auth(AuthError::Fail(failure.defined_condition)))) - } else if stanza.name() == "failure" { - // Workaround for https://gitlab.com/xmpp-rs/xmpp-parsers/merge_requests/1 - Box::new(err(Error::Auth(AuthError::Sasl("failure".to_string())))) - } else { + stream + .into_future() + .map_err(|(e, _stream)| e.into()) + .and_then(|(stanza, stream)| { + match stanza { + Some(Packet::Stanza(stanza)) => { + if let Ok(challenge) = Challenge::try_from(stanza.clone()) { + let response = mechanism.response(&challenge.data); + Box::new( + response + .map_err(|e| AuthError::Sasl(e).into()) + .into_future() + .and_then(|response| { + // Send response and loop + stream + .send_stanza(Response { data: response }) + .map_err(Error::Io) + .and_then(|stream| { + Self::handle_challenge(stream, mechanism) + }) + }), + ) + } else if let Ok(_) = Success::try_from(stanza.clone()) { + Box::new(ok(stream)) + } else if let Ok(failure) = Failure::try_from(stanza.clone()) { + Box::new(err(Error::Auth(AuthError::Fail( + failure.defined_condition, + )))) + } else if stanza.name() == "failure" { + // Workaround for https://gitlab.com/xmpp-rs/xmpp-parsers/merge_requests/1 + Box::new(err(Error::Auth(AuthError::Sasl("failure".to_string())))) + } else { + // ignore and loop + Self::handle_challenge(stream, mechanism) + } + } + Some(_) => { // ignore and loop Self::handle_challenge(stream, mechanism) } + None => Box::new(err(Error::Disconnected)), } - Some(_) => { - // ignore and loop - Self::handle_challenge(stream, mechanism) - } - None => Box::new(err(Error::Disconnected)) - } - }) + }), ) } } diff --git a/tokio-xmpp/src/client/bind.rs b/tokio-xmpp/src/client/bind.rs index f7d1828740dff5bfde15e22c01a4cba3ecfbdd6d..f164846f4cb47e6b73e2d8deb7374d51a80a0210 100644 --- a/tokio-xmpp/src/client/bind.rs +++ b/tokio-xmpp/src/client/bind.rs @@ -2,9 +2,9 @@ use futures::{sink, Async, Future, Poll, Stream}; use std::convert::TryFrom; use std::mem::replace; use tokio_io::{AsyncRead, AsyncWrite}; -use xmpp_parsers::Jid; use xmpp_parsers::bind::{BindQuery, BindResponse}; use xmpp_parsers::iq::{Iq, IqType}; +use xmpp_parsers::Jid; use crate::xmpp_codec::Packet; use crate::xmpp_stream::XMPPStream; diff --git a/tokio-xmpp/src/client/mod.rs b/tokio-xmpp/src/client/mod.rs index bcd07c954cac2f53b4571544fcefed19b6ce1c73..531f003baf54c624ce02d4874a09a186342f1240 100644 --- a/tokio-xmpp/src/client/mod.rs +++ b/tokio-xmpp/src/client/mod.rs @@ -1,12 +1,12 @@ use futures::{done, Async, AsyncSink, Future, Poll, Sink, StartSend, Stream}; use idna; -use xmpp_parsers::{Jid, JidParseError}; use sasl::common::{ChannelBinding, Credentials}; use std::mem::replace; use std::str::FromStr; use tokio::net::TcpStream; use tokio_io::{AsyncRead, AsyncWrite}; use tokio_tls::TlsStream; +use xmpp_parsers::{Jid, JidParseError}; use super::event::Event; use super::happy_eyeballs::Connecter; @@ -205,10 +205,8 @@ impl Sink for Client { fn start_send(&mut self, item: Self::SinkItem) -> StartSend { match self.state { - ClientState::Connected(ref mut stream) => - Ok(stream.start_send(item)?), - _ => - Ok(AsyncSink::NotReady(item)), + ClientState::Connected(ref mut stream) => Ok(stream.start_send(item)?), + _ => Ok(AsyncSink::NotReady(item)), } } @@ -226,11 +224,8 @@ impl Sink for Client { /// incoming stream before closing the connection. fn close(&mut self) -> Poll<(), Self::SinkError> { match self.state { - ClientState::Connected(ref mut stream) => - stream.close() - .map_err(|e| e.into()), - _ => - Ok(Async::Ready(())), + ClientState::Connected(ref mut stream) => stream.close().map_err(|e| e.into()), + _ => Ok(Async::Ready(())), } } } diff --git a/tokio-xmpp/src/component/mod.rs b/tokio-xmpp/src/component/mod.rs index d822e8839ae24993521f430191a62ac6fcd876d2..a111aacafaf48d9a30d0ed67e93ca7706073a59c 100644 --- a/tokio-xmpp/src/component/mod.rs +++ b/tokio-xmpp/src/component/mod.rs @@ -2,11 +2,11 @@ //! XMPP server under a JID consisting of just a domain name. They are //! allowed to use any user and resource identifiers in their stanzas. use futures::{done, Async, AsyncSink, Future, Poll, Sink, StartSend, Stream}; -use xmpp_parsers::{Jid, JidParseError, Element}; use std::mem::replace; use std::str::FromStr; use tokio::net::TcpStream; use tokio_io::{AsyncRead, AsyncWrite}; +use xmpp_parsers::{Element, Jid, JidParseError}; use super::event::Event; use super::happy_eyeballs::Connecter; diff --git a/tokio-xmpp/src/error.rs b/tokio-xmpp/src/error.rs index 68a1412e9f4d2b87c91c392514e2ec5f7b1217c6..498244425fe96e66945ac7d4163faf1fb791ac83 100644 --- a/tokio-xmpp/src/error.rs +++ b/tokio-xmpp/src/error.rs @@ -7,8 +7,8 @@ use std::str::Utf8Error; use trust_dns_proto::error::ProtoError; use trust_dns_resolver::error::ResolveError; -use xmpp_parsers::Error as ParsersError; use xmpp_parsers::sasl::DefinedCondition as SaslDefinedCondition; +use xmpp_parsers::Error as ParsersError; /// Top-level error type #[derive(Debug)] @@ -159,8 +159,12 @@ impl fmt::Display for ProtocolError { ProtocolError::Parser(e) => write!(fmt, "XML parser error: {}", e), ProtocolError::Parsers(e) => write!(fmt, "error with expected stanza schema: {}", e), ProtocolError::NoTls => write!(fmt, "no TLS available"), - ProtocolError::InvalidBindResponse => write!(fmt, "invalid response to resource binding"), - ProtocolError::NoStreamNamespace => write!(fmt, "no xmlns attribute in "), + ProtocolError::InvalidBindResponse => { + write!(fmt, "invalid response to resource binding") + } + ProtocolError::NoStreamNamespace => { + write!(fmt, "no xmlns attribute in ") + } ProtocolError::NoStreamId => write!(fmt, "no id attribute in "), ProtocolError::InvalidToken => write!(fmt, "encountered an unexpected XML token"), ProtocolError::InvalidStreamStart => write!(fmt, "unexpected "), diff --git a/tokio-xmpp/src/happy_eyeballs.rs b/tokio-xmpp/src/happy_eyeballs.rs index 7696f65e2cfa42f8903259b341719f381cc3b9b3..6cc75552125eb282122fdc39b087e1103c652dbc 100644 --- a/tokio-xmpp/src/happy_eyeballs.rs +++ b/tokio-xmpp/src/happy_eyeballs.rs @@ -8,11 +8,10 @@ use std::mem; use std::net::SocketAddr; use tokio::net::tcp::ConnectFuture; use tokio::net::TcpStream; -use trust_dns_resolver::{AsyncResolver, Name, IntoName, Background, BackgroundLookup}; use trust_dns_resolver::config::LookupIpStrategy; use trust_dns_resolver::lookup::SrvLookupFuture; use trust_dns_resolver::lookup_ip::LookupIpFuture; - +use trust_dns_resolver::{AsyncResolver, Background, BackgroundLookup, IntoName, Name}; enum State { ResolveSrv(AsyncResolver, BackgroundLookup), diff --git a/tokio-xmpp/src/starttls.rs b/tokio-xmpp/src/starttls.rs index e23402792b96ac6f858c8ead10df9a154414d966..6c5ba49294276534b639f090b4e8d9366ea9dbd3 100644 --- a/tokio-xmpp/src/starttls.rs +++ b/tokio-xmpp/src/starttls.rs @@ -1,11 +1,11 @@ use futures::sink; use futures::stream::Stream; use futures::{Async, Future, Poll, Sink}; -use xmpp_parsers::{Jid, Element}; use native_tls::TlsConnector as NativeTlsConnector; use std::mem::replace; use tokio_io::{AsyncRead, AsyncWrite}; use tokio_tls::{Connect, TlsConnector, TlsStream}; +use xmpp_parsers::{Element, Jid}; use crate::xmpp_codec::Packet; use crate::xmpp_stream::XMPPStream; diff --git a/tokio-xmpp/src/stream_start.rs b/tokio-xmpp/src/stream_start.rs index f82c3901e0aaf8f4d58adf2fd75af38621800b95..317a9f1ee3f80af01c0cd5d70e961ce2994d8451 100644 --- a/tokio-xmpp/src/stream_start.rs +++ b/tokio-xmpp/src/stream_start.rs @@ -1,8 +1,8 @@ use futures::{sink, Async, Future, Poll, Sink, Stream}; -use xmpp_parsers::{Jid, Element}; use std::mem::replace; use tokio_codec::Framed; use tokio_io::{AsyncRead, AsyncWrite}; +use xmpp_parsers::{Element, Jid}; use crate::xmpp_codec::{Packet, XMPPCodec}; use crate::xmpp_stream::XMPPStream; diff --git a/tokio-xmpp/src/xmpp_codec.rs b/tokio-xmpp/src/xmpp_codec.rs index 588d947d5c09898da7e6bbba36f3e6ff618fc218..39234069aef106614ab3e5de9daba32e736a1063 100644 --- a/tokio-xmpp/src/xmpp_codec.rs +++ b/tokio-xmpp/src/xmpp_codec.rs @@ -2,9 +2,9 @@ use crate::{ParseError, ParserError}; use bytes::{BufMut, BytesMut}; -use xmpp_parsers::Element; use quick_xml::Writer as EventWriter; use std; +use std::borrow::Cow; use std::cell::RefCell; use std::collections::vec_deque::VecDeque; use std::collections::HashMap; @@ -14,11 +14,11 @@ use std::io; use std::iter::FromIterator; use std::rc::Rc; use std::str::from_utf8; -use std::borrow::Cow; use tokio_codec::{Decoder, Encoder}; +use xml5ever::buffer_queue::BufferQueue; use xml5ever::interface::Attribute; use xml5ever::tokenizer::{Tag, TagKind, Token, TokenSink, XmlTokenizer}; -use xml5ever::buffer_queue::BufferQueue; +use xmpp_parsers::Element; /// Anything that can be sent or received on an XMPP/XML stream #[derive(Debug, Clone, PartialEq, Eq)] @@ -288,21 +288,17 @@ impl Encoder for XMPPCodec { match item { Packet::StreamStart(start_attrs) => { let mut buf = String::new(); - write!(buf, "\n") - .map_err(to_io_err)?; + write!(buf, ">\n").map_err(to_io_err)?; // print!(">> {}", buf); - write!(dst, "{}", buf) - .map_err(to_io_err) + write!(dst, "{}", buf).map_err(to_io_err) } Packet::Stanza(stanza) => { stanza @@ -321,10 +317,7 @@ impl Encoder for XMPPCodec { }) .map_err(to_io_err) } - Packet::StreamEnd => { - write!(dst, "\n") - .map_err(to_io_err) - } + Packet::StreamEnd => write!(dst, "\n").map_err(to_io_err), } } } @@ -483,10 +476,13 @@ mod tests { b.put(r"Test status"); let r = c.decode(&mut b); assert!(match r { - Ok(Some(Packet::Stanza(ref el))) if el.name() == "status" && el.text() == "Test status" && el.attr("xml:lang").map_or(false, |a| a == "en") => true, + Ok(Some(Packet::Stanza(ref el))) + if el.name() == "status" + && el.text() == "Test status" + && el.attr("xml:lang").map_or(false, |a| a == "en") => + true, _ => false, }); - } /// By default, encode() only get's a BytesMut that has 8kb space reserved. diff --git a/tokio-xmpp/src/xmpp_stream.rs b/tokio-xmpp/src/xmpp_stream.rs index 129dd1d4fe8825b06409cf52fac2f145f6678969..05e57156c3110b4b71981d4208592edb2991b4f8 100644 --- a/tokio-xmpp/src/xmpp_stream.rs +++ b/tokio-xmpp/src/xmpp_stream.rs @@ -2,9 +2,9 @@ use futures::sink::Send; use futures::{Poll, Sink, StartSend, Stream}; -use xmpp_parsers::{Jid, Element}; use tokio_codec::Framed; use tokio_io::{AsyncRead, AsyncWrite}; +use xmpp_parsers::{Element, Jid}; use crate::stream_start::StreamStart; use crate::xmpp_codec::{Packet, XMPPCodec}; diff --git a/xmpp-parsers/examples/generate-caps.rs b/xmpp-parsers/examples/generate-caps.rs index 80ba863f12be8e5f9f229638966fef8ac1d8f800..643b732008a8fbb5534831db42d0e2d04da56742 100644 --- a/xmpp-parsers/examples/generate-caps.rs +++ b/xmpp-parsers/examples/generate-caps.rs @@ -5,14 +5,14 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use std::convert::TryFrom; -use std::io::{self, Read}; use std::env; +use std::io::{self, Read}; use xmpp_parsers::{ - Element, + caps::{compute_disco as compute_disco_caps, hash_caps, Caps}, disco::DiscoInfoResult, - caps::{Caps, compute_disco as compute_disco_caps, hash_caps}, - ecaps2::{ECaps2, compute_disco as compute_disco_ecaps2, hash_ecaps2}, + ecaps2::{compute_disco as compute_disco_ecaps2, hash_ecaps2, ECaps2}, hashes::Algo, + Element, }; fn get_caps(disco: &DiscoInfoResult, node: String) -> Result { diff --git a/xmpp-parsers/src/bind.rs b/xmpp-parsers/src/bind.rs index 4da3564156abb8abd6025e0fa49fa9442508d11f..569cf744032faf0a9d34866146d68765dace78f1 100644 --- a/xmpp-parsers/src/bind.rs +++ b/xmpp-parsers/src/bind.rs @@ -4,13 +4,13 @@ // 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 crate::iq::{IqResultPayload, IqSetPayload}; use crate::ns; -use jid::{FullJid, Jid}; +use crate::util::error::Error; use crate::Element; -use std::str::FromStr; +use jid::{FullJid, Jid}; use std::convert::TryFrom; +use std::str::FromStr; /// The request for resource binding, which is the process by which a client /// can obtain a full JID and start exchanging on the XMPP network. @@ -63,10 +63,10 @@ impl From for Element { fn from(bind: BindQuery) -> Element { Element::builder("bind") .ns(ns::BIND) - .append_all(bind.resource.map(|resource| - Element::builder("resource") - .ns(ns::BIND) - .append(resource))) + .append_all( + bind.resource + .map(|resource| Element::builder("resource").ns(ns::BIND).append(resource)), + ) .build() } } @@ -115,10 +115,16 @@ impl TryFrom for BindResponse { } } - Ok(BindResponse { jid: match jid { - None => return Err(Error::ParseError("Bind response must contain a jid element.")), - Some(jid) => jid, - } }) + Ok(BindResponse { + jid: match jid { + None => { + return Err(Error::ParseError( + "Bind response must contain a jid element.", + )) + } + Some(jid) => jid, + }, + }) } } @@ -157,9 +163,10 @@ mod tests { let bind = BindQuery::try_from(elem).unwrap(); assert_eq!(bind.resource, None); - let elem: Element = "Hello™" - .parse() - .unwrap(); + let elem: Element = + "Hello™" + .parse() + .unwrap(); let bind = BindQuery::try_from(elem).unwrap(); // FIXME: “™” should be resourceprep’d into “TM” here… //assert_eq!(bind.resource.unwrap(), "HelloTM"); diff --git a/xmpp-parsers/src/blocking.rs b/xmpp-parsers/src/blocking.rs index 1ddfa5c9a6d7cddc6212577292308983aefbd009..c5c53f76e81bea139a2decbce576666ebbc276b6 100644 --- a/xmpp-parsers/src/blocking.rs +++ b/xmpp-parsers/src/blocking.rs @@ -4,11 +4,11 @@ // 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 crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload}; use crate::ns; -use jid::Jid; +use crate::util::error::Error; use crate::Element; +use jid::Jid; use std::convert::TryFrom; generate_empty_element!( diff --git a/xmpp-parsers/src/bob.rs b/xmpp-parsers/src/bob.rs index c78f6c34ed274ecf8c06fe498aa14385cb862b92..39cf738d00352e47c7bb3067a378609f48b3964d 100644 --- a/xmpp-parsers/src/bob.rs +++ b/xmpp-parsers/src/bob.rs @@ -4,9 +4,9 @@ // 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::hashes::{Hash, Algo}; -use crate::util::helpers::Base64; +use crate::hashes::{Algo, Hash}; use crate::util::error::Error; +use crate::util::helpers::Base64; use minidom::IntoAttributeValue; use std::str::FromStr; @@ -27,11 +27,11 @@ impl FromStr for ContentId { let temp: Vec<_> = match temp[..] { [lhs, rhs] => { if rhs != "bob.xmpp.org" { - return Err(Error::ParseError("Wrong domain for cid URI.")) + return Err(Error::ParseError("Wrong domain for cid URI.")); } lhs.splitn(2, '+').collect() - }, - _ => return Err(Error::ParseError("Missing @ in cid URI.")) + } + _ => return Err(Error::ParseError("Missing @ in cid URI.")), }; let (algo, hex) = match temp[..] { [lhs, rhs] => { @@ -41,8 +41,8 @@ impl FromStr for ContentId { _ => unimplemented!(), }; (algo, rhs) - }, - _ => return Err(Error::ParseError("Missing + in cid URI.")) + } + _ => return Err(Error::ParseError("Missing + in cid URI.")), }; let hash = Hash::from_hex(algo, hex)?; Ok(ContentId { hash }) @@ -108,15 +108,26 @@ mod tests { #[test] fn test_simple() { - let cid: ContentId = "sha1+8f35fef110ffc5df08d579a50083ff9308fb6242@bob.xmpp.org".parse().unwrap(); + let cid: ContentId = "sha1+8f35fef110ffc5df08d579a50083ff9308fb6242@bob.xmpp.org" + .parse() + .unwrap(); assert_eq!(cid.hash.algo, Algo::Sha_1); - assert_eq!(cid.hash.hash, b"\x8f\x35\xfe\xf1\x10\xff\xc5\xdf\x08\xd5\x79\xa5\x00\x83\xff\x93\x08\xfb\x62\x42"); - assert_eq!(cid.into_attribute_value().unwrap(), "sha1+8f35fef110ffc5df08d579a50083ff9308fb6242@bob.xmpp.org"); + assert_eq!( + cid.hash.hash, + b"\x8f\x35\xfe\xf1\x10\xff\xc5\xdf\x08\xd5\x79\xa5\x00\x83\xff\x93\x08\xfb\x62\x42" + ); + assert_eq!( + cid.into_attribute_value().unwrap(), + "sha1+8f35fef110ffc5df08d579a50083ff9308fb6242@bob.xmpp.org" + ); let elem: Element = "".parse().unwrap(); let data = Data::try_from(elem).unwrap(); assert_eq!(data.cid.hash.algo, Algo::Sha_1); - assert_eq!(data.cid.hash.hash, b"\x8f\x35\xfe\xf1\x10\xff\xc5\xdf\x08\xd5\x79\xa5\x00\x83\xff\x93\x08\xfb\x62\x42"); + assert_eq!( + data.cid.hash.hash, + b"\x8f\x35\xfe\xf1\x10\xff\xc5\xdf\x08\xd5\x79\xa5\x00\x83\xff\x93\x08\xfb\x62\x42" + ); assert!(data.max_age.is_none()); assert!(data.type_.is_none()); assert!(data.data.is_empty()); @@ -138,14 +149,18 @@ mod tests { }; assert_eq!(message, "Missing + in cid URI."); - let error = "sha1+1234@coucou.linkmauve.fr".parse::().unwrap_err(); + let error = "sha1+1234@coucou.linkmauve.fr" + .parse::() + .unwrap_err(); let message = match error { Error::ParseError(string) => string, _ => panic!(), }; assert_eq!(message, "Wrong domain for cid URI."); - let error = "sha1+invalid@bob.xmpp.org".parse::().unwrap_err(); + let error = "sha1+invalid@bob.xmpp.org" + .parse::() + .unwrap_err(); let message = match error { Error::ParseIntError(error) => error, _ => panic!(), diff --git a/xmpp-parsers/src/bookmarks2.rs b/xmpp-parsers/src/bookmarks2.rs index 2a182f12a613dfcd9580e4490bf3a07df17959d3..cf3eaf614c43f1da3609d08c38e6e315e7479455 100644 --- a/xmpp-parsers/src/bookmarks2.rs +++ b/xmpp-parsers/src/bookmarks2.rs @@ -45,12 +45,12 @@ impl Conference { #[cfg(test)] mod tests { use super::*; + use crate::ns; + use crate::pubsub::event::PubSubEvent; + use crate::pubsub::pubsub::Item as PubSubItem; use crate::util::compare_elements::NamespaceAwareCompare; use crate::Element; use std::convert::TryFrom; - use crate::pubsub::pubsub::Item as PubSubItem; - use crate::pubsub::event::PubSubEvent; - use crate::ns; #[cfg(target_pointer_width = "32")] #[test] @@ -66,7 +66,9 @@ mod tests { #[test] fn simple() { - let elem: Element = "".parse().unwrap(); + let elem: Element = "" + .parse() + .unwrap(); let elem1 = elem.clone(); let conference = Conference::try_from(elem).unwrap(); assert_eq!(conference.autojoin, Autojoin::False); @@ -104,7 +106,7 @@ mod tests { Ok(PubSubEvent::PublishedItems { node, items }) => { assert_eq!(&node.0, ns::BOOKMARKS2); items - }, + } _ => panic!(), }; assert_eq!(items.len(), 1); diff --git a/xmpp-parsers/src/caps.rs b/xmpp-parsers/src/caps.rs index 96ffa22adefe47fcf24891c7df2aec091ab14cba..579b70bc9f0eaf3312c82089a4500fa0bb96092e 100644 --- a/xmpp-parsers/src/caps.rs +++ b/xmpp-parsers/src/caps.rs @@ -6,13 +6,13 @@ use crate::data_forms::DataForm; use crate::disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity}; -use crate::util::error::Error; use crate::hashes::{Algo, Hash}; use crate::ns; use crate::presence::PresencePayload; +use crate::util::error::Error; +use crate::Element; use blake2::VarBlake2b; use digest::{Digest, Input, VariableOutput}; -use crate::Element; use sha1::Sha1; use sha2::{Sha256, Sha512}; use sha3::{Sha3_256, Sha3_512}; diff --git a/xmpp-parsers/src/cert_management.rs b/xmpp-parsers/src/cert_management.rs index 817a01bb284fcdb81cff9a2e36a6e8ec333aa79d..106b16096fb2e42b2af422d0c27b436ec3ca7ce9 100644 --- a/xmpp-parsers/src/cert_management.rs +++ b/xmpp-parsers/src/cert_management.rs @@ -4,12 +4,14 @@ // 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::iq::{IqSetPayload, IqGetPayload, IqResultPayload}; +use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload}; use crate::util::helpers::Base64; generate_elem_id!( /// The name of a certificate. - Name, "name", SASL_CERT + Name, + "name", + SASL_CERT ); generate_element!( @@ -40,14 +42,18 @@ impl IqSetPayload for Append {} generate_empty_element!( /// Client requests the current list of X.509 certificates. - ListCertsQuery, "items", SASL_CERT + ListCertsQuery, + "items", + SASL_CERT ); impl IqGetPayload for ListCertsQuery {} generate_elem_id!( /// One resource currently using a certificate. - Resource, "resource", SASL_CERT + Resource, + "resource", + SASL_CERT ); generate_element!( @@ -113,10 +119,10 @@ impl IqSetPayload for Revoke {} #[cfg(test)] mod tests { use super::*; + use crate::ns; use crate::Element; use std::convert::TryFrom; use std::str::FromStr; - use crate::ns; #[cfg(target_pointer_width = "32")] #[test] @@ -153,11 +159,17 @@ mod tests { assert_eq!(append.name.0, "Mobile Client"); assert_eq!(append.cert.data, b"\0\0\0"); - let elem: Element = "Mobile Client".parse().unwrap(); + let elem: Element = + "Mobile Client" + .parse() + .unwrap(); let disable = Disable::try_from(elem).unwrap(); assert_eq!(disable.name.0, "Mobile Client"); - let elem: Element = "Mobile Client".parse().unwrap(); + let elem: Element = + "Mobile Client" + .parse() + .unwrap(); let revoke = Revoke::try_from(elem).unwrap(); assert_eq!(revoke.name.0, "Mobile Client"); } @@ -177,7 +189,9 @@ mod tests { Laptop BBBB - "#.parse().unwrap(); + "# + .parse() + .unwrap(); let mut list = ListCertsResponse::try_from(elem).unwrap(); assert_eq!(list.items.len(), 2); @@ -196,7 +210,9 @@ mod tests { fn test_serialise() { let append = Append { name: Name::from_str("Mobile Client").unwrap(), - cert: Cert { data: b"\0\0\0".to_vec() }, + cert: Cert { + data: b"\0\0\0".to_vec(), + }, no_cert_management: false, }; let elem: Element = append.into(); diff --git a/xmpp-parsers/src/chatstates.rs b/xmpp-parsers/src/chatstates.rs index 4d8f9a4dbb7edcf17cb0919a6ee785407eb00359..5e98112bbb070e1935775048391ff1735b0fb4a9 100644 --- a/xmpp-parsers/src/chatstates.rs +++ b/xmpp-parsers/src/chatstates.rs @@ -32,8 +32,8 @@ impl MessagePayload for ChatState {} #[cfg(test)] mod tests { use super::*; - use crate::util::error::Error; use crate::ns; + use crate::util::error::Error; use crate::Element; use std::convert::TryFrom; diff --git a/xmpp-parsers/src/csi.rs b/xmpp-parsers/src/csi.rs index f3a9130d4afca79f24f772517dbbead2de9ef501..bfd44f8469ffd749eb72ca991e62fc4a160205b9 100644 --- a/xmpp-parsers/src/csi.rs +++ b/xmpp-parsers/src/csi.rs @@ -6,25 +6,31 @@ generate_empty_element!( /// Stream:feature sent by the server to advertise it supports CSI. - Feature, "csi", CSI + Feature, + "csi", + CSI ); generate_empty_element!( /// Client indicates it is inactive. - Inactive, "inactive", CSI + Inactive, + "inactive", + CSI ); generate_empty_element!( /// Client indicates it is active again. - Active, "active", CSI + Active, + "active", + CSI ); #[cfg(test)] mod tests { use super::*; + use crate::ns; use crate::Element; use std::convert::TryFrom; - use crate::ns; #[test] fn test_size() { diff --git a/xmpp-parsers/src/data_forms.rs b/xmpp-parsers/src/data_forms.rs index 37f94dfa541e068694b8830b45eeddab99ddaff0..3fda6a4047a193c37d1ad2258dbeb926a1d03786 100644 --- a/xmpp-parsers/src/data_forms.rs +++ b/xmpp-parsers/src/data_forms.rs @@ -4,9 +4,9 @@ // 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 crate::media_element::MediaElement; use crate::ns; +use crate::util::error::Error; use crate::Element; use std::convert::TryFrom; @@ -162,11 +162,7 @@ impl From for Element { field .values .into_iter() - .map(|value| { - Element::builder("value") - .ns(ns::DATA_FORMS) - .append(value) - }) + .map(|value| Element::builder("value").ns(ns::DATA_FORMS).append(value)), ) .append_all(field.media.iter().cloned().map(Element::from)) .build() @@ -287,9 +283,11 @@ impl From for Element { .ns(ns::DATA_FORMS) .attr("var", "FORM_TYPE") .attr("type", "hidden") - .append(Element::builder("value") - .ns(ns::DATA_FORMS) - .append(form_type)) + .append( + Element::builder("value") + .ns(ns::DATA_FORMS) + .append(form_type), + ) })) .append_all(form.fields.iter().cloned().map(Element::from)) .build() diff --git a/xmpp-parsers/src/delay.rs b/xmpp-parsers/src/delay.rs index e7c7449a73d3e4fafc3832439fbaf520770828ca..fcb9447905f9744ffe96ad1a9195804d91ef8a66 100644 --- a/xmpp-parsers/src/delay.rs +++ b/xmpp-parsers/src/delay.rs @@ -5,9 +5,9 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use crate::date::DateTime; -use crate::util::helpers::PlainText; use crate::message::MessagePayload; use crate::presence::PresencePayload; +use crate::util::helpers::PlainText; use jid::Jid; generate_element!( @@ -34,8 +34,8 @@ mod tests { use super::*; use crate::util::error::Error; use crate::Element; - use std::str::FromStr; use std::convert::TryFrom; + use std::str::FromStr; #[cfg(target_pointer_width = "32")] #[test] diff --git a/xmpp-parsers/src/disco.rs b/xmpp-parsers/src/disco.rs index 040ce8c42e9b4d94f242d09092240b3c80f9ca67..2041819e56e84b5faa31894a444916c9d7ad2532 100644 --- a/xmpp-parsers/src/disco.rs +++ b/xmpp-parsers/src/disco.rs @@ -5,11 +5,11 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use crate::data_forms::{DataForm, DataFormType}; -use crate::util::error::Error; use crate::iq::{IqGetPayload, IqResultPayload}; use crate::ns; -use jid::Jid; +use crate::util::error::Error; use crate::Element; +use jid::Jid; use std::convert::TryFrom; generate_element!( @@ -37,9 +37,7 @@ attributes: [ impl Feature { /// Create a new `` with the according `@var`. pub fn new>(var: S) -> Feature { - Feature { - var: var.into(), - } + Feature { var: var.into() } } } @@ -66,10 +64,11 @@ generate_element!( impl Identity { /// Create a new ``. pub fn new(category: C, type_: T, lang: L, name: N) -> Identity - where C: Into, - T: Into, - L: Into, - N: Into, + where + C: Into, + T: Into, + L: Into, + N: Into, { Identity { category: category.into(), @@ -81,8 +80,9 @@ impl Identity { /// Create a new `` without a name. pub fn new_anonymous(category: C, type_: T) -> Identity - where C: Into, - T: Into, + where + C: Into, + T: Into, { Identity { category: category.into(), @@ -340,10 +340,7 @@ mod tests { Error::ParseError(string) => string, _ => panic!(), }; - assert_eq!( - message, - "Required attribute 'category' must not be empty." - ); + assert_eq!(message, "Required attribute 'category' must not be empty."); let elem: Element = "".parse().unwrap(); let error = DiscoInfoResult::try_from(elem).unwrap_err(); diff --git a/xmpp-parsers/src/ecaps2.rs b/xmpp-parsers/src/ecaps2.rs index cfcb340f34a1891465f015736174104d6c51beb8..b6fc41a870a41d86764f30b6058a5bc395b4678d 100644 --- a/xmpp-parsers/src/ecaps2.rs +++ b/xmpp-parsers/src/ecaps2.rs @@ -30,9 +30,7 @@ impl PresencePayload for ECaps2 {} impl ECaps2 { /// Create an ECaps2 element from a list of hashes. pub fn new(hashes: Vec) -> ECaps2 { - ECaps2 { - hashes, - } + ECaps2 { hashes } } } @@ -85,7 +83,13 @@ fn compute_extensions(extensions: &[DataForm]) -> Result, ()> { } Ok(compute_items(extensions, 0x1c, |extension| { let mut bytes = compute_item("FORM_TYPE"); - bytes.append(&mut compute_item(if let Some(ref form_type) = extension.form_type { form_type } else { unreachable!() })); + bytes.append(&mut compute_item( + if let Some(ref form_type) = extension.form_type { + form_type + } else { + unreachable!() + }, + )); bytes.push(0x1e); bytes.append(&mut compute_items(&extension.fields, 0x1d, |field| { let mut bytes = compute_item(&field.var); diff --git a/xmpp-parsers/src/hashes.rs b/xmpp-parsers/src/hashes.rs index 56b61355507471a549f96caf3125910009b5d307..b80532e3b728f0f79ba2f7db3db02568d11dab62 100644 --- a/xmpp-parsers/src/hashes.rs +++ b/xmpp-parsers/src/hashes.rs @@ -236,8 +236,14 @@ mod tests { fn value_serialisation() { let elem: Element = "2XarmwTlNxDAMkvymloX3S5+VbylNrJt/l5QyPa+YoU=".parse().unwrap(); let hash = Hash::try_from(elem).unwrap(); - assert_eq!(hash.to_base64(), "2XarmwTlNxDAMkvymloX3S5+VbylNrJt/l5QyPa+YoU="); - assert_eq!(hash.to_hex(), "d976ab9b04e53710c0324bf29a5a17dd2e7e55bca536b26dfe5e50c8f6be6285"); + assert_eq!( + hash.to_base64(), + "2XarmwTlNxDAMkvymloX3S5+VbylNrJt/l5QyPa+YoU=" + ); + assert_eq!( + hash.to_hex(), + "d976ab9b04e53710c0324bf29a5a17dd2e7e55bca536b26dfe5e50c8f6be6285" + ); assert_eq!(hash.to_colon_separated_hex(), "d9:76:ab:9b:04:e5:37:10:c0:32:4b:f2:9a:5a:17:dd:2e:7e:55:bc:a5:36:b2:6d:fe:5e:50:c8:f6:be:62:85"); } diff --git a/xmpp-parsers/src/ibb.rs b/xmpp-parsers/src/ibb.rs index 719fd8537e66390ba8722dc8c9edaafecad4c6ec..17d26764799f5d0d22cd60f66b334336554acf4b 100644 --- a/xmpp-parsers/src/ibb.rs +++ b/xmpp-parsers/src/ibb.rs @@ -4,8 +4,8 @@ // 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::helpers::Base64; use crate::iq::IqSetPayload; +use crate::util::helpers::Base64; generate_id!( /// An identifier matching a stream. @@ -74,8 +74,8 @@ mod tests { use super::*; use crate::util::error::Error; use crate::Element; - use std::error::Error as StdError; use std::convert::TryFrom; + use std::error::Error as StdError; #[cfg(target_pointer_width = "32")] #[test] diff --git a/xmpp-parsers/src/ibr.rs b/xmpp-parsers/src/ibr.rs index b1b15286653395d7b63bb619d342f91ecd3a2bd8..72f582ffebd1eb45f3b8e74d26d6668a43364427 100644 --- a/xmpp-parsers/src/ibr.rs +++ b/xmpp-parsers/src/ibr.rs @@ -5,9 +5,9 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use crate::data_forms::DataForm; -use crate::util::error::Error; use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload}; use crate::ns; +use crate::util::error::Error; use crate::Element; use std::collections::HashMap; use std::convert::TryFrom; @@ -102,7 +102,7 @@ impl From for Element { query .fields .into_iter() - .map(|(name, value)| Element::builder(name).ns(ns::REGISTER).append(value)) + .map(|(name, value)| Element::builder(name).ns(ns::REGISTER).append(value)), ) .append_all(if query.remove { Some(Element::builder("remove").ns(ns::REGISTER)) diff --git a/xmpp-parsers/src/idle.rs b/xmpp-parsers/src/idle.rs index 47d1c18335c7627c7f20449b21eba42cd491927d..e06de9a595786c22620e23dbb202669cb9cb46e3 100644 --- a/xmpp-parsers/src/idle.rs +++ b/xmpp-parsers/src/idle.rs @@ -23,9 +23,9 @@ mod tests { use super::*; use crate::util::error::Error; use crate::Element; + use std::convert::TryFrom; use std::error::Error as StdError; use std::str::FromStr; - use std::convert::TryFrom; #[test] fn test_size() { diff --git a/xmpp-parsers/src/iq.rs b/xmpp-parsers/src/iq.rs index 644926163157e0e0dedea535fe9adbb5c7db5023..05535283280e544f50c7ab35593f4ee0a25d755f 100644 --- a/xmpp-parsers/src/iq.rs +++ b/xmpp-parsers/src/iq.rs @@ -5,11 +5,11 @@ // 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 crate::ns; use crate::stanza_error::StanzaError; -use jid::Jid; +use crate::util::error::Error; use crate::Element; +use jid::Jid; use minidom::IntoAttributeValue; use std::convert::TryFrom; @@ -218,9 +218,9 @@ impl From for Element { #[cfg(test)] mod tests { use super::*; - use crate::util::compare_elements::NamespaceAwareCompare; use crate::disco::DiscoInfoQuery; use crate::stanza_error::{DefinedCondition, ErrorType}; + use crate::util::compare_elements::NamespaceAwareCompare; #[cfg(target_pointer_width = "32")] #[test] @@ -252,7 +252,9 @@ mod tests { #[cfg(not(feature = "component"))] let elem: Element = "".parse().unwrap(); #[cfg(feature = "component")] - let elem: Element = "".parse().unwrap(); + let elem: Element = "" + .parse() + .unwrap(); let error = Iq::try_from(elem).unwrap_err(); let message = match error { Error::ParseError(string) => string, @@ -314,7 +316,9 @@ mod tests { #[test] fn test_result_empty() { #[cfg(not(feature = "component"))] - let elem: Element = "".parse().unwrap(); + let elem: Element = "" + .parse() + .unwrap(); #[cfg(feature = "component")] let elem: Element = "" .parse() @@ -416,7 +420,9 @@ mod tests { #[test] fn test_serialise() { #[cfg(not(feature = "component"))] - let elem: Element = "".parse().unwrap(); + let elem: Element = "" + .parse() + .unwrap(); #[cfg(feature = "component")] let elem: Element = "" .parse() diff --git a/xmpp-parsers/src/jid_prep.rs b/xmpp-parsers/src/jid_prep.rs index 5fbc0a0c0f3f7ab29bf42f978cd329ab248af273..5f596e89696071495fb88a9ef3906ae595fa2de0 100644 --- a/xmpp-parsers/src/jid_prep.rs +++ b/xmpp-parsers/src/jid_prep.rs @@ -5,7 +5,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use crate::iq::{IqGetPayload, IqResultPayload}; -use crate::util::helpers::{Text, JidCodec}; +use crate::util::helpers::{JidCodec, Text}; use jid::Jid; generate_element!( @@ -22,9 +22,7 @@ impl IqGetPayload for JidPrepQuery {} impl JidPrepQuery { /// Create a new JID Prep query. pub fn new>(jid: J) -> JidPrepQuery { - JidPrepQuery { - data: jid.into(), - } + JidPrepQuery { data: jid.into() } } } @@ -62,12 +60,19 @@ mod tests { #[test] fn simple() { - let elem: Element = "ROMeo@montague.lit/orchard".parse().unwrap(); + let elem: Element = "ROMeo@montague.lit/orchard" + .parse() + .unwrap(); let query = JidPrepQuery::try_from(elem).unwrap(); assert_eq!(query.data, "ROMeo@montague.lit/orchard"); - let elem: Element = "romeo@montague.lit/orchard".parse().unwrap(); + let elem: Element = "romeo@montague.lit/orchard" + .parse() + .unwrap(); let response = JidPrepResponse::try_from(elem).unwrap(); - assert_eq!(response.jid, Jid::from_str("romeo@montague.lit/orchard").unwrap()); + assert_eq!( + response.jid, + Jid::from_str("romeo@montague.lit/orchard").unwrap() + ); } } diff --git a/xmpp-parsers/src/jingle.rs b/xmpp-parsers/src/jingle.rs index 82875686b8d6835eb4e0d2a894ac4eec03730429..94edfc7bebdb91c59737ef843ee9937efff17262 100644 --- a/xmpp-parsers/src/jingle.rs +++ b/xmpp-parsers/src/jingle.rs @@ -4,18 +4,18 @@ // 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 crate::iq::IqSetPayload; -use crate::jingle_rtp::Description as RtpDescription; -use crate::jingle_ice_udp::Transport as IceUdpTransport; use crate::jingle_ibb::Transport as IbbTransport; +use crate::jingle_ice_udp::Transport as IceUdpTransport; +use crate::jingle_rtp::Description as RtpDescription; use crate::jingle_s5b::Transport as Socks5Transport; use crate::ns; -use jid::Jid; +use crate::util::error::Error; use crate::Element; +use jid::Jid; use std::collections::BTreeMap; -use std::str::FromStr; use std::convert::TryFrom; +use std::str::FromStr; generate_attribute!( /// The action attribute. @@ -473,8 +473,8 @@ impl From for Element { Reason::UnsupportedApplications => "unsupported-applications", Reason::UnsupportedTransports => "unsupported-transports", }) - .ns(ns::JINGLE) - .build() + .ns(ns::JINGLE) + .build() } } @@ -521,13 +521,8 @@ impl TryFrom for ReasonElement { return Err(Error::ParseError("Reason contains a foreign element.")); } } - let reason = reason.ok_or(Error::ParseError( - "Reason doesn’t contain a valid reason.", - ))?; - Ok(ReasonElement { - reason, - texts, - }) + let reason = reason.ok_or(Error::ParseError("Reason doesn’t contain a valid reason."))?; + Ok(ReasonElement { reason, texts }) } } @@ -536,13 +531,12 @@ impl From for Element { Element::builder("reason") .ns(ns::JINGLE) .append(Element::from(reason.reason)) - .append_all( - reason.texts.into_iter().map(|(lang, text)| { - Element::builder("text") - .ns(ns::JINGLE) - .attr("xml:lang", lang) - .append(text) - })) + .append_all(reason.texts.into_iter().map(|(lang, text)| { + Element::builder("text") + .ns(ns::JINGLE) + .attr("xml:lang", lang) + .append(text) + })) .build() } } diff --git a/xmpp-parsers/src/jingle_dtls_srtp.rs b/xmpp-parsers/src/jingle_dtls_srtp.rs index e6a3ee235730fa3c102e41064c6b07a87764da0f..a586946821a7c971d530db0c068d5b5d5f2c9834 100644 --- a/xmpp-parsers/src/jingle_dtls_srtp.rs +++ b/xmpp-parsers/src/jingle_dtls_srtp.rs @@ -4,9 +4,9 @@ // 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::helpers::ColonSeparatedHex; +use crate::hashes::{Algo, Hash}; use crate::util::error::Error; -use crate::hashes::{Hash, Algo}; +use crate::util::helpers::ColonSeparatedHex; generate_attribute!( /// Indicates which of the end points should initiate the TCP connection establishment. @@ -58,7 +58,11 @@ impl Fingerprint { } /// Create a new Fingerprint from a Setup and parsing the hash. - pub fn from_colon_separated_hex(setup: Setup, algo: &str, hash: &str) -> Result { + pub fn from_colon_separated_hex( + setup: Setup, + algo: &str, + hash: &str, + ) -> Result { let algo = algo.parse()?; let hash = Hash::from_colon_separated_hex(algo, hash)?; Ok(Fingerprint::from_hash(setup, hash)) @@ -93,6 +97,12 @@ mod tests { let fingerprint = Fingerprint::try_from(elem).unwrap(); assert_eq!(fingerprint.setup, Setup::Actpass); assert_eq!(fingerprint.hash, Algo::Sha_256); - assert_eq!(fingerprint.value, [2, 26, 204, 84, 39, 171, 235, 156, 83, 63, 62, 75, 101, 46, 125, 70, 63, 84, 66, 205, 84, 241, 122, 3, 162, 125, 249, 176, 127, 70, 25, 178]); + assert_eq!( + fingerprint.value, + [ + 2, 26, 204, 84, 39, 171, 235, 156, 83, 63, 62, 75, 101, 46, 125, 70, 63, 84, 66, + 205, 84, 241, 122, 3, 162, 125, 249, 176, 127, 70, 25, 178 + ] + ); } } diff --git a/xmpp-parsers/src/jingle_ft.rs b/xmpp-parsers/src/jingle_ft.rs index f3fc9a33fdad6ac7d5e221df9e7d2f31586e6434..2bd1adc9c2babd05482579a469ace4c3318757d3 100644 --- a/xmpp-parsers/src/jingle_ft.rs +++ b/xmpp-parsers/src/jingle_ft.rs @@ -5,14 +5,14 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use crate::date::DateTime; -use crate::util::error::Error; use crate::hashes::Hash; use crate::jingle::{ContentId, Creator}; use crate::ns; +use crate::util::error::Error; use minidom::{Element, Node}; use std::collections::BTreeMap; -use std::str::FromStr; use std::convert::TryFrom; +use std::str::FromStr; generate_element!( /// Represents a range in a file. @@ -195,22 +195,21 @@ impl From for Element { fn from(file: File) -> Element { Element::builder("file") .ns(ns::JINGLE_FT) - .append_all(file.date.map(|date| - Element::builder("date") - .append(date))) - .append_all(file.media_type.map(|media_type| - Element::builder("media-type") - .append(media_type))) - .append_all(file.name.map(|name| - Element::builder("name") - .append(name))) - .append_all(file.descs.into_iter().map(|(lang, desc)| + .append_all(file.date.map(|date| Element::builder("date").append(date))) + .append_all( + file.media_type + .map(|media_type| Element::builder("media-type").append(media_type)), + ) + .append_all(file.name.map(|name| Element::builder("name").append(name))) + .append_all(file.descs.into_iter().map(|(lang, desc)| { Element::builder("desc") .attr("xml:lang", lang) - .append(desc.0))) - .append_all(file.size.map(|size| - Element::builder("size") - .append(format!("{}", size)))) + .append(desc.0) + })) + .append_all( + file.size + .map(|size| Element::builder("size").append(format!("{}", size))), + ) .append_all(file.range) .append_all(file.hashes) .build() diff --git a/xmpp-parsers/src/jingle_ibb.rs b/xmpp-parsers/src/jingle_ibb.rs index f0fb90f0f8a12b43758d046b8f1cf7933fa8e99d..d980b5e3ca9af15672ade773cf5b554b5011fa1a 100644 --- a/xmpp-parsers/src/jingle_ibb.rs +++ b/xmpp-parsers/src/jingle_ibb.rs @@ -26,8 +26,8 @@ mod tests { use super::*; use crate::util::error::Error; use crate::Element; - use std::error::Error as StdError; use std::convert::TryFrom; + use std::error::Error as StdError; #[cfg(target_pointer_width = "32")] #[test] diff --git a/xmpp-parsers/src/jingle_ice_udp.rs b/xmpp-parsers/src/jingle_ice_udp.rs index b7f9e777886a2e686355b88a96b1d15f3b6620e5..1f5dada9e4f6148b14a43d8d1e19b2f512b6850c 100644 --- a/xmpp-parsers/src/jingle_ice_udp.rs +++ b/xmpp-parsers/src/jingle_ice_udp.rs @@ -115,10 +115,10 @@ generate_element!( #[cfg(test)] mod tests { use super::*; - use crate::Element; - use std::convert::TryFrom; use crate::hashes::Algo; use crate::jingle_dtls_srtp::Setup; + use crate::Element; + use std::convert::TryFrom; #[cfg(target_pointer_width = "32")] #[test] @@ -184,6 +184,12 @@ mod tests { let fingerprint = transport.fingerprint.unwrap(); assert_eq!(fingerprint.hash, Algo::Sha_1); assert_eq!(fingerprint.setup, Setup::Actpass); - assert_eq!(fingerprint.value, [151, 242, 181, 190, 219, 166, 0, 177, 62, 64, 178, 65, 60, 13, 252, 224, 189, 178, 160, 232]); + assert_eq!( + fingerprint.value, + [ + 151, 242, 181, 190, 219, 166, 0, 177, 62, 64, 178, 65, 60, 13, 252, 224, 189, 178, + 160, 232 + ] + ); } } diff --git a/xmpp-parsers/src/jingle_message.rs b/xmpp-parsers/src/jingle_message.rs index 78bf1db22ca38112eae8b3a363ce9563e8515b9d..ab1840e93c196811c8b9d613f636da15858829a8 100644 --- a/xmpp-parsers/src/jingle_message.rs +++ b/xmpp-parsers/src/jingle_message.rs @@ -4,9 +4,9 @@ // 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 crate::jingle::SessionId; use crate::ns; +use crate::util::error::Error; use crate::Element; use std::convert::TryFrom; diff --git a/xmpp-parsers/src/jingle_rtcp_fb.rs b/xmpp-parsers/src/jingle_rtcp_fb.rs index da52b88794b23c581bc39334f4bf4a817504db79..d02a589d1193c2208e30096a7d118cbaf73cc8ec 100644 --- a/xmpp-parsers/src/jingle_rtcp_fb.rs +++ b/xmpp-parsers/src/jingle_rtcp_fb.rs @@ -36,7 +36,8 @@ mod tests { #[test] fn parse_simple() { - let elem: Element = "" + let elem: Element = + "" .parse() .unwrap(); let rtcp_fb = RtcpFb::try_from(elem).unwrap(); diff --git a/xmpp-parsers/src/jingle_rtp.rs b/xmpp-parsers/src/jingle_rtp.rs index 4fa596a991a12db2bc049eeae18f18c239cc38a0..88f9cdad696100a425edeb8d40ffd42e26983120 100644 --- a/xmpp-parsers/src/jingle_rtp.rs +++ b/xmpp-parsers/src/jingle_rtp.rs @@ -4,8 +4,8 @@ // 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::jingle_ssma::{Source, Group}; use crate::jingle_rtcp_fb::RtcpFb; +use crate::jingle_ssma::{Group, Source}; generate_element!( /// Wrapper element describing an RTP session. @@ -48,7 +48,10 @@ impl Description { generate_attribute!( /// The number of channels. - Channels, "channels", u8, Default = 1 + Channels, + "channels", + u8, + Default = 1 ); generate_element!( diff --git a/xmpp-parsers/src/jingle_s5b.rs b/xmpp-parsers/src/jingle_s5b.rs index b6df19ed6d835abb8f7b5e4779366b9ea715d2c9..2d7208046017d841dfafda8b8c061b0b9cb3d559 100644 --- a/xmpp-parsers/src/jingle_s5b.rs +++ b/xmpp-parsers/src/jingle_s5b.rs @@ -4,12 +4,12 @@ // 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 crate::ns; -use jid::Jid; +use crate::util::error::Error; use crate::Element; -use std::net::IpAddr; +use jid::Jid; use std::convert::TryFrom; +use std::net::IpAddr; generate_attribute!( /// The type of the connection being proposed by this candidate. @@ -263,9 +263,9 @@ impl From for Element { .ns(ns::JINGLE_S5B) .attr("cid", cid) .build()], - TransportPayload::ProxyError => vec![Element::builder("proxy-error") - .ns(ns::JINGLE_S5B) - .build()], + TransportPayload::ProxyError => { + vec![Element::builder("proxy-error").ns(ns::JINGLE_S5B).build()] + } TransportPayload::None => vec![], }) .build() diff --git a/xmpp-parsers/src/jingle_ssma.rs b/xmpp-parsers/src/jingle_ssma.rs index 4d966b86ff8dd0676150363ee352b0228ee7fede..877a8b17ff92cfefe1e7cf2b922859f26e3bbb24 100644 --- a/xmpp-parsers/src/jingle_ssma.rs +++ b/xmpp-parsers/src/jingle_ssma.rs @@ -88,7 +88,10 @@ mod tests { assert_eq!(ssrc.parameters.len(), 2); let parameter = ssrc.parameters.pop().unwrap(); assert_eq!(parameter.name, "msid"); - assert_eq!(parameter.value.unwrap(), "MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIv MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIva0"); + assert_eq!( + parameter.value.unwrap(), + "MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIv MLTJKIHilGn71fNQoszkQ4jlPTuS5vJyKVIva0" + ); let parameter = ssrc.parameters.pop().unwrap(); assert_eq!(parameter.name, "cname"); assert_eq!(parameter.value.unwrap(), "Yv/wvbCdsDW2Prgd"); @@ -101,8 +104,8 @@ mod tests { " - .parse() - .unwrap(); + .parse() + .unwrap(); let mut group = Group::try_from(elem).unwrap(); assert_eq!(group.semantics, "FID"); assert_eq!(group.sources.len(), 2); diff --git a/xmpp-parsers/src/lib.rs b/xmpp-parsers/src/lib.rs index 4977a8bc9937aab5a9840bb20e52d42602a052e8..8af2c52b0d8d325a74fe3463315fb39be5c4a242 100644 --- a/xmpp-parsers/src/lib.rs +++ b/xmpp-parsers/src/lib.rs @@ -23,9 +23,9 @@ #![deny(missing_docs)] -pub use minidom::Element; -pub use jid::{BareJid, FullJid, Jid, JidParseError}; pub use crate::util::error::Error; +pub use jid::{BareJid, FullJid, Jid, JidParseError}; +pub use minidom::Element; /// XML namespace definitions used through XMPP. pub mod ns; diff --git a/xmpp-parsers/src/mam.rs b/xmpp-parsers/src/mam.rs index 28362bf917c7081d49c28757434af018a485c9b6..1f6bc5f92839ebf6c0c098fe6ed237861ece2319 100644 --- a/xmpp-parsers/src/mam.rs +++ b/xmpp-parsers/src/mam.rs @@ -5,13 +5,13 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use crate::data_forms::DataForm; -use crate::util::error::Error; use crate::forwarding::Forwarded; use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload}; use crate::message::MessagePayload; use crate::ns; use crate::pubsub::NodeName; use crate::rsm::{SetQuery, SetResult}; +use crate::util::error::Error; use jid::Jid; use minidom::{Element, Node}; use std::convert::TryFrom; @@ -168,14 +168,14 @@ fn serialise_jid_list(name: &str, jids: Vec) -> ::std::option::IntoIter for Element { .attr("to", message.to) .attr("id", message.id) .attr("type", message.type_) - .append_all( - message - .subjects - .into_iter() - .map(|(lang, subject)| { - let mut subject = Element::from(subject); - subject.set_attr( - "xml:lang", - match lang.as_ref() { - "" => None, - lang => Some(lang), - }, - ); - subject - }) - ) - .append_all( - message - .bodies - .into_iter() - .map(|(lang, body)| { - let mut body = Element::from(body); - body.set_attr( - "xml:lang", - match lang.as_ref() { - "" => None, - lang => Some(lang), - }, - ); - body - }) - ) + .append_all(message.subjects.into_iter().map(|(lang, subject)| { + let mut subject = Element::from(subject); + subject.set_attr( + "xml:lang", + match lang.as_ref() { + "" => None, + lang => Some(lang), + }, + ); + subject + })) + .append_all(message.bodies.into_iter().map(|(lang, body)| { + let mut body = Element::from(body); + body.set_attr( + "xml:lang", + match lang.as_ref() { + "" => None, + lang => Some(lang), + }, + ); + body + })) .append_all(message.payloads.into_iter()) .build() } diff --git a/xmpp-parsers/src/muc/muc.rs b/xmpp-parsers/src/muc/muc.rs index 01688ec3623c4a073a8482fcd7592e520695c3fd..935edd5f8213aa6a7fa01dc8598bbed71a1e0b7e 100644 --- a/xmpp-parsers/src/muc/muc.rs +++ b/xmpp-parsers/src/muc/muc.rs @@ -97,8 +97,8 @@ mod tests { use crate::util::compare_elements::NamespaceAwareCompare; use crate::util::error::Error; use crate::Element; - use std::str::FromStr; use std::convert::TryFrom; + use std::str::FromStr; #[test] fn test_muc_simple() { diff --git a/xmpp-parsers/src/muc/user.rs b/xmpp-parsers/src/muc/user.rs index 31157f7681d7b367f98336d24ec11344cb27e93d..b90298e05c91cab4fc796ceef41ddee4c7e7b33d 100644 --- a/xmpp-parsers/src/muc/user.rs +++ b/xmpp-parsers/src/muc/user.rs @@ -5,10 +5,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 crate::ns; -use jid::FullJid; +use crate::util::error::Error; use crate::Element; +use jid::FullJid; use std::convert::TryFrom; generate_attribute_enum!( @@ -99,11 +99,9 @@ impl TryFrom for Actor { let nick = get_attr!(elem, "nick", Option); match (jid, nick) { - (Some(_), Some(_)) | (None, None) => { - Err(Error::ParseError( - "Either 'jid' or 'nick' attribute is required.", - )) - } + (Some(_), Some(_)) | (None, None) => Err(Error::ParseError( + "Either 'jid' or 'nick' attribute is required.", + )), (Some(jid), _) => Ok(Actor::Jid(jid)), (_, Some(nick)) => Ok(Actor::Nick(nick)), } diff --git a/xmpp-parsers/src/occupant_id.rs b/xmpp-parsers/src/occupant_id.rs index 418a878bd5729fb44d0d8b266cb32a8083aee383..fd11b5b492448826e5dfb8dd8983155aaa7df9b2 100644 --- a/xmpp-parsers/src/occupant_id.rs +++ b/xmpp-parsers/src/occupant_id.rs @@ -66,7 +66,9 @@ mod tests { #[test] fn test_invalid_id() { - let elem: Element = "".parse().unwrap(); + let elem: Element = "" + .parse() + .unwrap(); let error = OccupantId::try_from(elem).unwrap_err(); let message = match error { Error::ParseError(string) => string, diff --git a/xmpp-parsers/src/openpgp.rs b/xmpp-parsers/src/openpgp.rs index 86f4829a77fa8af1fae6448a3aa27b3635418e6b..f0cb892ad4b98bceb24369ee8d34d710138fba43 100644 --- a/xmpp-parsers/src/openpgp.rs +++ b/xmpp-parsers/src/openpgp.rs @@ -5,8 +5,8 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use crate::date::DateTime; -use crate::util::helpers::Base64; use crate::pubsub::PubSubPayload; +use crate::util::helpers::Base64; // TODO: Merge this container with the PubKey struct generate_element!( @@ -59,8 +59,11 @@ impl PubSubPayload for PubKeysMeta {} mod tests { use super::*; use crate::ns; + use crate::pubsub::{ + pubsub::{Item as PubSubItem, Publish}, + Item, NodeName, + }; use std::str::FromStr; - use crate::pubsub::{NodeName, Item, pubsub::{Item as PubSubItem, Publish}}; #[test] fn pubsub_publish_pubkey_data() { @@ -68,15 +71,13 @@ mod tests { date: None, data: PubKeyData { data: (&"Foo").as_bytes().to_vec(), - } + }, }; println!("Foo1: {:?}", pubkey); let pubsub = Publish { node: NodeName(format!("{}:{}", ns::OX_PUBKEYS, "some-fingerprint")), - items: vec![ - PubSubItem(Item::new(None, None, Some(pubkey))), - ], + items: vec![PubSubItem(Item::new(None, None, Some(pubkey)))], }; println!("Foo2: {:?}", pubsub); } @@ -84,20 +85,16 @@ mod tests { #[test] fn pubsub_publish_pubkey_meta() { let pubkeymeta = PubKeysMeta { - pubkeys: vec![ - PubKeyMeta { - v4fingerprint: "some-fingerprint".to_owned(), - date: DateTime::from_str("2019-03-30T18:30:25Z").unwrap(), - }, - ], + pubkeys: vec![PubKeyMeta { + v4fingerprint: "some-fingerprint".to_owned(), + date: DateTime::from_str("2019-03-30T18:30:25Z").unwrap(), + }], }; println!("Foo1: {:?}", pubkeymeta); let pubsub = Publish { node: NodeName("foo".to_owned()), - items: vec![ - PubSubItem(Item::new(None, None, Some(pubkeymeta))), - ], + items: vec![PubSubItem(Item::new(None, None, Some(pubkeymeta)))], }; println!("Foo2: {:?}", pubsub); } diff --git a/xmpp-parsers/src/presence.rs b/xmpp-parsers/src/presence.rs index b096a7b0967cee24c0c7f21c04a08fb286246dc5..082eefbb6821bbd8ef4dc0915f4f373ebbd4a73a 100644 --- a/xmpp-parsers/src/presence.rs +++ b/xmpp-parsers/src/presence.rs @@ -5,13 +5,13 @@ // 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 crate::ns; +use crate::util::error::Error; use jid::Jid; use minidom::{Element, IntoAttributeValue, Node}; use std::collections::BTreeMap; -use std::str::FromStr; use std::convert::TryFrom; +use std::str::FromStr; /// Should be implemented on every known payload of a ``. pub trait PresencePayload: TryFrom + Into {} @@ -232,8 +232,9 @@ impl Presence { /// Set the availability information of this presence. pub fn set_status(&mut self, lang: L, status: S) - where L: Into, - S: Into, + where + L: Into, + S: Into, { self.statuses.insert(lang.into(), status.into()); } @@ -310,27 +311,21 @@ impl From for Element { .attr("id", presence.id) .attr("type", presence.type_) .append_all(presence.show.into_iter()) - .append_all( - presence - .statuses - .into_iter() - .map(|(lang, status)| { - Element::builder("status") - .attr( - "xml:lang", - match lang.as_ref() { - "" => None, - lang => Some(lang), - }, - ) - .append(status) - }) - ) + .append_all(presence.statuses.into_iter().map(|(lang, status)| { + Element::builder("status") + .attr( + "xml:lang", + match lang.as_ref() { + "" => None, + lang => Some(lang), + }, + ) + .append(status) + })) .append_all(if presence.priority == 0 { None } else { - Some(Element::builder("priority") - .append(format!("{}", presence.priority))) + Some(Element::builder("priority").append(format!("{}", presence.priority))) }) .append_all(presence.payloads.into_iter()) .build() @@ -409,9 +404,7 @@ mod tests { #[test] fn test_empty_show_value() { #[cfg(not(feature = "component"))] - let elem: Element = "" - .parse() - .unwrap(); + let elem: Element = "".parse().unwrap(); #[cfg(feature = "component")] let elem: Element = "" .parse() @@ -623,8 +616,7 @@ mod tests { #[test] fn test_serialise_priority() { - let presence = Presence::new(Type::None) - .with_priority(42); + let presence = Presence::new(Type::None).with_priority(42); let elem: Element = presence.into(); assert!(elem.is("presence", ns::DEFAULT_NS)); let priority = elem.children().next().unwrap(); @@ -638,23 +630,24 @@ mod tests { let elem: Element = presence.into(); assert_eq!(elem.attr("to"), None); - let presence = Presence::new(Type::None) - .with_to(Jid::Bare(BareJid::domain("localhost"))); + let presence = Presence::new(Type::None).with_to(Jid::Bare(BareJid::domain("localhost"))); let elem: Element = presence.into(); assert_eq!(elem.attr("to"), Some("localhost")); - let presence = Presence::new(Type::None) - .with_to(BareJid::domain("localhost")); + let presence = Presence::new(Type::None).with_to(BareJid::domain("localhost")); let elem: Element = presence.into(); assert_eq!(elem.attr("to"), Some("localhost")); - let presence = Presence::new(Type::None) - .with_to(Jid::Full(FullJid::new("test", "localhost", "coucou"))); + let presence = Presence::new(Type::None).with_to(Jid::Full(FullJid::new( + "test", + "localhost", + "coucou", + ))); let elem: Element = presence.into(); assert_eq!(elem.attr("to"), Some("test@localhost/coucou")); - let presence = Presence::new(Type::None) - .with_to(FullJid::new("test", "localhost", "coucou")); + let presence = + Presence::new(Type::None).with_to(FullJid::new("test", "localhost", "coucou")); let elem: Element = presence.into(); assert_eq!(elem.attr("to"), Some("test@localhost/coucou")); } diff --git a/xmpp-parsers/src/pubsub/event.rs b/xmpp-parsers/src/pubsub/event.rs index 2228a067dd1ea49af5b73598414e3d3d72a5f5f3..322a79f5092b5e6efdc0bef4500a6d7088e0ba74 100644 --- a/xmpp-parsers/src/pubsub/event.rs +++ b/xmpp-parsers/src/pubsub/event.rs @@ -6,11 +6,11 @@ use crate::data_forms::DataForm; use crate::date::DateTime; -use crate::util::error::Error; use crate::ns; -use crate::pubsub::{ItemId, NodeName, Subscription, SubscriptionId, Item as PubSubItem}; -use jid::Jid; +use crate::pubsub::{Item as PubSubItem, ItemId, NodeName, Subscription, SubscriptionId}; +use crate::util::error::Error; use crate::Element; +use jid::Jid; use std::convert::TryFrom; /// Event wrapper for a PubSub ``. @@ -214,15 +214,11 @@ impl From for Element { PubSubEvent::RetractedItems { node, items } => Element::builder("items") .ns(ns::PUBSUB_EVENT) .attr("node", node) - .append_all( - items - .into_iter() - .map(|id| { - Element::builder("retract") - .ns(ns::PUBSUB_EVENT) - .attr("id", id) - }) - ), + .append_all(items.into_iter().map(|id| { + Element::builder("retract") + .ns(ns::PUBSUB_EVENT) + .attr("id", id) + })), PubSubEvent::Purge { node } => Element::builder("purge") .ns(ns::PUBSUB_EVENT) .attr("node", node), diff --git a/xmpp-parsers/src/pubsub/mod.rs b/xmpp-parsers/src/pubsub/mod.rs index 4b998b9febddc61c341e82d28edf88a1ebde497d..ee668ffb52c45a7925b67ec768174e3652e149b8 100644 --- a/xmpp-parsers/src/pubsub/mod.rs +++ b/xmpp-parsers/src/pubsub/mod.rs @@ -13,7 +13,7 @@ pub mod pubsub; pub use self::event::PubSubEvent; pub use self::pubsub::PubSub; -use crate::{Jid, Element}; +use crate::{Element, Jid}; generate_id!( /// The name of a PubSub node, used to identify it on a JID. @@ -63,7 +63,11 @@ pub struct Item { impl Item { /// Create a new item, accepting only payloads implementing `PubSubPayload`. - pub fn new(id: Option, publisher: Option, payload: Option

) -> Item { + pub fn new( + id: Option, + publisher: Option, + payload: Option

, + ) -> Item { Item { id, publisher, diff --git a/xmpp-parsers/src/pubsub/pubsub.rs b/xmpp-parsers/src/pubsub/pubsub.rs index 39b30c7427ab6abf379d3d880e78cd71826cd927..24ad3c480777a98d4a068f9521f89c236c3012fa 100644 --- a/xmpp-parsers/src/pubsub/pubsub.rs +++ b/xmpp-parsers/src/pubsub/pubsub.rs @@ -5,12 +5,12 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use crate::data_forms::DataForm; -use crate::util::error::Error; use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload}; use crate::ns; -use crate::pubsub::{NodeName, Subscription, SubscriptionId, Item as PubSubItem}; -use jid::Jid; +use crate::pubsub::{Item as PubSubItem, NodeName, Subscription, SubscriptionId}; +use crate::util::error::Error; use crate::Element; +use jid::Jid; use std::convert::TryFrom; // TODO: a better solution would be to split this into a query and a result elements, like for diff --git a/xmpp-parsers/src/receipts.rs b/xmpp-parsers/src/receipts.rs index e837a17fdcedf984266206c513561f5433dc4847..62fd7b777943b499f6c56bd1c37445a91e07c4e9 100644 --- a/xmpp-parsers/src/receipts.rs +++ b/xmpp-parsers/src/receipts.rs @@ -32,9 +32,9 @@ impl MessagePayload for Received {} mod tests { use super::*; use crate::ns; + use crate::util::error::Error; use crate::Element; use std::convert::TryFrom; - use crate::util::error::Error; #[cfg(target_pointer_width = "32")] #[test] diff --git a/xmpp-parsers/src/roster.rs b/xmpp-parsers/src/roster.rs index 730da52df65f0b2f3d2e0a0ae9f9c607e3f1caa0..3153e4662a2a5c1413d4d47af7b94c1654e85304 100644 --- a/xmpp-parsers/src/roster.rs +++ b/xmpp-parsers/src/roster.rs @@ -95,8 +95,8 @@ mod tests { use crate::util::compare_elements::NamespaceAwareCompare; use crate::util::error::Error; use crate::Element; - use std::str::FromStr; use std::convert::TryFrom; + use std::str::FromStr; #[cfg(target_pointer_width = "32")] #[test] diff --git a/xmpp-parsers/src/rsm.rs b/xmpp-parsers/src/rsm.rs index 169681d1e911f47aed85802c0cae31aaf92e12b0..f59235bffe1ae082e99291e1b02e252e07b14491 100644 --- a/xmpp-parsers/src/rsm.rs +++ b/xmpp-parsers/src/rsm.rs @@ -4,8 +4,8 @@ // 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 crate::ns; +use crate::util::error::Error; use crate::Element; use std::convert::TryFrom; @@ -79,13 +79,12 @@ impl From for Element { })) .append_all( set.after - .map(|after| Element::builder("after").ns(ns::RSM).append(after)) + .map(|after| Element::builder("after").ns(ns::RSM).append(after)), + ) + .append_all( + set.before + .map(|before| Element::builder("before").ns(ns::RSM).append(before)), ) - .append_all(set.before.map(|before| { - Element::builder("before") - .ns(ns::RSM) - .append(before) - })) .append_all(set.index.map(|index| { Element::builder("index") .ns(ns::RSM) diff --git a/xmpp-parsers/src/sasl.rs b/xmpp-parsers/src/sasl.rs index e3f0900576adf0f29af36d679f68e398a16283bd..e001a2603e0418a3b53a414a5c6d078dd7faae3e 100644 --- a/xmpp-parsers/src/sasl.rs +++ b/xmpp-parsers/src/sasl.rs @@ -4,9 +4,9 @@ // 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::ns; use crate::util::error::Error; use crate::util::helpers::Base64; -use crate::ns; use crate::Element; use std::collections::BTreeMap; use std::convert::TryFrom; @@ -203,17 +203,12 @@ impl From for Element { Element::builder("failure") .ns(ns::SASL) .append(failure.defined_condition) - .append_all( - failure - .texts - .into_iter() - .map(|(lang, text)| { - Element::builder("text") - .ns(ns::SASL) - .attr("xml:lang", lang) - .append(text) - }) - ) + .append_all(failure.texts.into_iter().map(|(lang, text)| { + Element::builder("text") + .ns(ns::SASL) + .attr("xml:lang", lang) + .append(text) + })) .build() } } diff --git a/xmpp-parsers/src/stanza_error.rs b/xmpp-parsers/src/stanza_error.rs index 0bdc2887f1c36a55dc62a7dba7927ee64cf7cdb7..f9ec648ad1b23a5dac4cb93226e27649c2b5792f 100644 --- a/xmpp-parsers/src/stanza_error.rs +++ b/xmpp-parsers/src/stanza_error.rs @@ -4,12 +4,12 @@ // 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 crate::message::MessagePayload; use crate::ns; use crate::presence::PresencePayload; -use jid::Jid; +use crate::util::error::Error; use crate::Element; +use jid::Jid; use std::collections::BTreeMap; use std::convert::TryFrom; @@ -217,9 +217,15 @@ impl PresencePayload for StanzaError {} impl StanzaError { /// Create a new `` with the according content. - pub fn new(type_: ErrorType, defined_condition: DefinedCondition, lang: L, text: T) -> StanzaError - where L: Into, - T: Into, + pub fn new( + type_: ErrorType, + defined_condition: DefinedCondition, + lang: L, + text: T, + ) -> StanzaError + where + L: Into, + T: Into, { StanzaError { type_, @@ -294,14 +300,12 @@ impl From for Element { .attr("type", err.type_) .attr("by", err.by) .append(err.defined_condition) - .append_all( - err.texts.into_iter().map(|(lang, text)| { - Element::builder("text") - .ns(ns::XMPP_STANZAS) - .attr("xml:lang", lang) - .append(text) - }) - ) + .append_all(err.texts.into_iter().map(|(lang, text)| { + Element::builder("text") + .ns(ns::XMPP_STANZAS) + .attr("xml:lang", lang) + .append(text) + })) .append_all(err.other) .build() } diff --git a/xmpp-parsers/src/stanza_id.rs b/xmpp-parsers/src/stanza_id.rs index 1ba48f85da115c69d93a790b021b0eee6fd1e418..a8696bfde7f05f48018081c8b6d0cf09d24a5c35 100644 --- a/xmpp-parsers/src/stanza_id.rs +++ b/xmpp-parsers/src/stanza_id.rs @@ -39,8 +39,8 @@ mod tests { use super::*; use crate::util::error::Error; use crate::Element; - use std::str::FromStr; use std::convert::TryFrom; + use std::str::FromStr; #[cfg(target_pointer_width = "32")] #[test] diff --git a/xmpp-parsers/src/time.rs b/xmpp-parsers/src/time.rs index 363cd210890eb6de2f0427ad02e4058c17d56fe5..0bfbc5305c2aaabd330a57c011a2549bd1638286 100644 --- a/xmpp-parsers/src/time.rs +++ b/xmpp-parsers/src/time.rs @@ -4,18 +4,20 @@ // 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 chrono::FixedOffset; use crate::date::DateTime; use crate::iq::{IqGetPayload, IqResultPayload}; use crate::ns; use crate::util::error::Error; use crate::Element; +use chrono::FixedOffset; use std::convert::TryFrom; use std::str::FromStr; generate_empty_element!( /// An entity time query. - TimeQuery, "time", TIME + TimeQuery, + "time", + TIME ); impl IqGetPayload for TimeQuery {} @@ -59,9 +61,7 @@ impl TryFrom for TimeResult { } utc = Some(date_time); } else { - return Err(Error::ParseError( - "Unknown child in time element.", - )); + return Err(Error::ParseError("Unknown child in time element.")); } } @@ -77,10 +77,11 @@ impl From for Element { fn from(time: TimeResult) -> Element { Element::builder("time") .ns(ns::TIME) - .append(Element::builder("tzo") - .append(format!("{}", time.0.timezone()))) - .append(Element::builder("utc") - .append(time.0.with_timezone(FixedOffset::east(0)).format("%FT%TZ"))) + .append(Element::builder("tzo").append(format!("{}", time.0.timezone()))) + .append( + Element::builder("utc") + .append(time.0.with_timezone(FixedOffset::east(0)).format("%FT%TZ")), + ) .build() } } @@ -105,7 +106,10 @@ mod tests { let elem1 = elem.clone(); let time = TimeResult::try_from(elem).unwrap(); assert_eq!(time.0.timezone(), FixedOffset::west(6 * 3600)); - assert_eq!(time.0, DateTime::from_str("2006-12-19T12:58:35-05:00").unwrap()); + assert_eq!( + time.0, + DateTime::from_str("2006-12-19T12:58:35-05:00").unwrap() + ); let elem2 = Element::from(time); assert_eq!(elem1, elem2); } diff --git a/xmpp-parsers/src/tune.rs b/xmpp-parsers/src/tune.rs index ed35357d8bef5e9b4e7fdd7854e6de13bd516e1a..bc81d9d88b763ba983017cc2929281e78abb795b 100644 --- a/xmpp-parsers/src/tune.rs +++ b/xmpp-parsers/src/tune.rs @@ -4,49 +4,63 @@ // 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 crate::pubsub::PubSubPayload; use crate::ns; +use crate::pubsub::PubSubPayload; +use crate::util::error::Error; use crate::Element; use std::convert::TryFrom; generate_elem_id!( /// The artist or performer of the song or piece. - Artist, "artist", TUNE + Artist, + "artist", + TUNE ); generate_elem_id!( /// The duration of the song or piece in seconds. - Length, "length", TUNE, + Length, + "length", + TUNE, u16 ); generate_elem_id!( /// The user's rating of the song or piece, from 1 (lowest) to 10 (highest). - Rating, "rating", TUNE, + Rating, + "rating", + TUNE, u8 ); generate_elem_id!( /// The collection (e.g., album) or other source (e.g., a band website that hosts streams or /// audio files). - Source, "source", TUNE + Source, + "source", + TUNE ); generate_elem_id!( /// The title of the song or piece. - Title, "title", TUNE + Title, + "title", + TUNE ); generate_elem_id!( /// A unique identifier for the tune; e.g., the track number within a collection or the /// specific URI for the object (e.g., a stream or audio file). - Track, "track", TUNE + Track, + "track", + TUNE ); generate_elem_id!( /// A URI or URL pointing to information about the song, collection, or artist. - Uri, "uri", TUNE + Uri, + "uri", + TUNE ); /// Container for formatted text. @@ -221,8 +235,14 @@ mod tests { assert_eq!(tune.length, Some(Length(686))); assert_eq!(tune.rating, Some(Rating(8))); assert_eq!(tune.source, Some(Source::from_str("Yessongs").unwrap())); - assert_eq!(tune.title, Some(Title::from_str("Heart of the Sunrise").unwrap())); + assert_eq!( + tune.title, + Some(Title::from_str("Heart of the Sunrise").unwrap()) + ); assert_eq!(tune.track, Some(Track::from_str("3").unwrap())); - assert_eq!(tune.uri, Some(Uri::from_str("http://www.yesworld.com/lyrics/Fragile.html#9").unwrap())); + assert_eq!( + tune.uri, + Some(Uri::from_str("http://www.yesworld.com/lyrics/Fragile.html#9").unwrap()) + ); } } diff --git a/xmpp-parsers/src/util/helpers.rs b/xmpp-parsers/src/util/helpers.rs index 7bf3feb1f2b59e453bd4dd58694aa9083e1d6f3e..570e7cfc4a17626a32e150094f7c7e97c5744922 100644 --- a/xmpp-parsers/src/util/helpers.rs +++ b/xmpp-parsers/src/util/helpers.rs @@ -71,7 +71,10 @@ pub struct WhitespaceAwareBase64; impl WhitespaceAwareBase64 { pub fn decode(s: &str) -> Result, Error> { - let s: String = s.chars().filter(|ch| *ch != ' ' && *ch != '\n' && *ch != '\t').collect(); + let s: String = s + .chars() + .filter(|ch| *ch != ' ' && *ch != '\n' && *ch != '\t') + .collect(); Ok(base64::decode(&s)?) } diff --git a/xmpp-parsers/src/util/macros.rs b/xmpp-parsers/src/util/macros.rs index d703e258325dbb0a03a67ee46a64f6712d29afe2..13807e9dcee7274486c78474e5739ba342781b72 100644 --- a/xmpp-parsers/src/util/macros.rs +++ b/xmpp-parsers/src/util/macros.rs @@ -41,7 +41,7 @@ macro_rules! get_attr { $attr, "' must not be empty." ))); - }, + } Some($value) => $func, None => { return Err(crate::util::error::Error::ParseError(concat!( @@ -601,41 +601,42 @@ macro_rules! generate_serialiser { $builder.append( crate::Element::builder($name) .ns(crate::ns::$ns) - .append(::minidom::Node::Text($parent.$elem)) + .append(::minidom::Node::Text($parent.$elem)), ) }; ($builder:ident, $parent:ident, $elem:ident, Option, String, ($name:tt, $ns:ident)) => { $builder.append_all($parent.$elem.map(|elem| { - crate::Element::builder($name) - .ns(crate::ns::$ns) - .append(::minidom::Node::Text(elem)) - }) - ) + crate::Element::builder($name) + .ns(crate::ns::$ns) + .append(::minidom::Node::Text(elem)) + })) }; ($builder:ident, $parent:ident, $elem:ident, Option, $constructor:ident, ($name:tt, *)) => { $builder.append_all($parent.$elem.map(|elem| { - crate::Element::builder($name) - .ns(elem.get_ns()) - .append(::minidom::Node::Element(crate::Element::from(elem))) - }) - ) + crate::Element::builder($name) + .ns(elem.get_ns()) + .append(::minidom::Node::Element(crate::Element::from(elem))) + })) }; ($builder:ident, $parent:ident, $elem:ident, Option, $constructor:ident, ($name:tt, $ns:ident)) => { $builder.append_all($parent.$elem.map(|elem| { - crate::Element::builder($name) - .ns(crate::ns::$ns) - .append(::minidom::Node::Element(crate::Element::from(elem))) - }) - ) + crate::Element::builder($name) + .ns(crate::ns::$ns) + .append(::minidom::Node::Element(crate::Element::from(elem))) + })) }; ($builder:ident, $parent:ident, $elem:ident, Vec, $constructor:ident, ($name:tt, $ns:ident)) => { $builder.append_all($parent.$elem.into_iter()) }; ($builder:ident, $parent:ident, $elem:ident, Present, $constructor:ident, ($name:tt, $ns:ident)) => { - $builder.append(::minidom::Node::Element(crate::Element::builder($name).ns(crate::ns::$ns).build())) + $builder.append(::minidom::Node::Element( + crate::Element::builder($name).ns(crate::ns::$ns).build(), + )) }; ($builder:ident, $parent:ident, $elem:ident, $_:ident, $constructor:ident, ($name:tt, $ns:ident)) => { - $builder.append(::minidom::Node::Element(crate::Element::from($parent.$elem))) + $builder.append(::minidom::Node::Element(crate::Element::from( + $parent.$elem, + ))) }; } @@ -804,5 +805,5 @@ macro_rules! impl_pubsub_item { &mut self.0 } } - } + }; } diff --git a/xmpp-parsers/src/xhtml.rs b/xmpp-parsers/src/xhtml.rs index 080fb4a2e4e0d604f4efed8342fe1a034d11df45..6049a5fb4e57d517fc4e6a5912508ed99b08b78e 100644 --- a/xmpp-parsers/src/xhtml.rs +++ b/xmpp-parsers/src/xhtml.rs @@ -4,12 +4,12 @@ // 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 crate::message::MessagePayload; use crate::ns; +use crate::util::error::Error; use minidom::{Element, Node}; -use std::convert::TryFrom; use std::collections::HashMap; +use std::convert::TryFrom; // TODO: Use a proper lang type. type Lang = String; @@ -51,15 +51,10 @@ impl XhtmlIm { } acc }); - let body = Body { - children, - ..body - }; + let body = Body { children, ..body }; bodies.insert(lang, body); } - XhtmlIm { - bodies, - } + XhtmlIm { bodies } } } @@ -79,11 +74,16 @@ impl TryFrom for XhtmlIm { let lang = match child.attr("xml:lang") { Some(lang) => lang, None => "", - }.to_string(); + } + .to_string(); let body = Body::try_from(child)?; match bodies.insert(lang, body) { None => (), - Some(_) => return Err(Error::ParseError("Two identical language bodies found in XHTML-IM.")) + Some(_) => { + return Err(Error::ParseError( + "Two identical language bodies found in XHTML-IM.", + )) + } } } else { return Err(Error::ParseError("Unknown element in XHTML-IM.")); @@ -160,11 +160,15 @@ impl TryFrom for Body { match child { Node::Element(child) => children.push(Child::Tag(Tag::try_from(child.clone())?)), Node::Text(text) => children.push(Child::Text(text.clone())), - Node::Comment(_) => unimplemented!() // XXX: remove! + Node::Comment(_) => unimplemented!(), // XXX: remove! } } - Ok(Body { style: parse_css(elem.attr("style")), xml_lang: elem.attr("xml:lang").map(|xml_lang| xml_lang.to_string()), children }) + Ok(Body { + style: parse_css(elem.attr("style")), + xml_lang: elem.attr("xml:lang").map(|xml_lang| xml_lang.to_string()), + children, + }) } } @@ -181,39 +185,87 @@ impl From for Element { #[derive(Debug, Clone)] enum Tag { - A { href: Option, style: Css, type_: Option, children: Vec }, - Blockquote { style: Css, children: Vec }, + A { + href: Option, + style: Css, + type_: Option, + children: Vec, + }, + Blockquote { + style: Css, + children: Vec, + }, Br, - Cite { style: Css, children: Vec }, - Em { children: Vec }, - Img { src: Option, alt: Option }, // TODO: height, width, style - Li { style: Css, children: Vec }, - Ol { style: Css, children: Vec }, - P { style: Css, children: Vec }, - Span { style: Css, children: Vec }, - Strong { children: Vec }, - Ul { style: Css, children: Vec }, + Cite { + style: Css, + children: Vec, + }, + Em { + children: Vec, + }, + Img { + src: Option, + alt: Option, + }, // TODO: height, width, style + Li { + style: Css, + children: Vec, + }, + Ol { + style: Css, + children: Vec, + }, + P { + style: Css, + children: Vec, + }, + Span { + style: Css, + children: Vec, + }, + Strong { + children: Vec, + }, + Ul { + style: Css, + children: Vec, + }, Unknown(Vec), } impl Tag { fn to_html(self) -> String { match self { - Tag::A { href, style, type_, children } => { + Tag::A { + href, + style, + type_, + children, + } => { let href = write_attr(href, "href"); let style = write_attr(get_style_string(style), "style"); let type_ = write_attr(type_, "type"); - format!("{}", href, style, type_, children_to_html(children)) - }, + format!( + "{}", + href, + style, + type_, + children_to_html(children) + ) + } Tag::Blockquote { style, children } => { let style = write_attr(get_style_string(style), "style"); - format!("{}", style, children_to_html(children)) - }, + format!( + "{}", + style, + children_to_html(children) + ) + } Tag::Br => String::from("
"), Tag::Cite { style, children } => { let style = write_attr(get_style_string(style), "style"); format!("{}", style, children_to_html(children)) - }, + } Tag::Em { children } => format!("{}", children_to_html(children)), Tag::Img { src, alt } => { let src = write_attr(src, "src"); @@ -241,7 +293,9 @@ impl Tag { let style = write_attr(get_style_string(style), "style"); format!("{}", style, children_to_html(children)) } - Tag::Unknown(_) => panic!("No unknown element should be present in XHTML-IM after parsing."), + Tag::Unknown(_) => { + panic!("No unknown element should be present in XHTML-IM after parsing.") + } } } } @@ -255,23 +309,52 @@ impl TryFrom for Tag { match child { Node::Element(child) => children.push(Child::Tag(Tag::try_from(child.clone())?)), Node::Text(text) => children.push(Child::Text(text.clone())), - Node::Comment(_) => unimplemented!() // XXX: remove! + Node::Comment(_) => unimplemented!(), // XXX: remove! } } Ok(match elem.name() { - "a" => Tag::A { href: elem.attr("href").map(|href| href.to_string()), style: parse_css(elem.attr("style")), type_: elem.attr("type").map(|type_| type_.to_string()), children }, - "blockquote" => Tag::Blockquote { style: parse_css(elem.attr("style")), children }, + "a" => Tag::A { + href: elem.attr("href").map(|href| href.to_string()), + style: parse_css(elem.attr("style")), + type_: elem.attr("type").map(|type_| type_.to_string()), + children, + }, + "blockquote" => Tag::Blockquote { + style: parse_css(elem.attr("style")), + children, + }, "br" => Tag::Br, - "cite" => Tag::Cite { style: parse_css(elem.attr("style")), children }, + "cite" => Tag::Cite { + style: parse_css(elem.attr("style")), + children, + }, "em" => Tag::Em { children }, - "img" => Tag::Img { src: elem.attr("src").map(|src| src.to_string()), alt: elem.attr("alt").map(|alt| alt.to_string()) }, - "li" => Tag::Li { style: parse_css(elem.attr("style")), children }, - "ol" => Tag::Ol { style: parse_css(elem.attr("style")), children }, - "p" => Tag::P { style: parse_css(elem.attr("style")), children }, - "span" => Tag::Span { style: parse_css(elem.attr("style")), children }, + "img" => Tag::Img { + src: elem.attr("src").map(|src| src.to_string()), + alt: elem.attr("alt").map(|alt| alt.to_string()), + }, + "li" => Tag::Li { + style: parse_css(elem.attr("style")), + children, + }, + "ol" => Tag::Ol { + style: parse_css(elem.attr("style")), + children, + }, + "p" => Tag::P { + style: parse_css(elem.attr("style")), + children, + }, + "span" => Tag::Span { + style: parse_css(elem.attr("style")), + children, + }, "strong" => Tag::Strong { children }, - "ul" => Tag::Ul { style: parse_css(elem.attr("style")), children }, + "ul" => Tag::Ul { + style: parse_css(elem.attr("style")), + children, + }, _ => Tag::Unknown(children), }) } @@ -280,28 +363,45 @@ impl TryFrom for Tag { impl From for Element { fn from(tag: Tag) -> Element { let (name, attrs, children) = match tag { - Tag::A { href, style, type_, children } => ("a", { - let mut attrs = vec![]; - if let Some(href) = href { - attrs.push(("href", href)); - } - if let Some(style) = get_style_string(style) { - attrs.push(("style", style)); - } - if let Some(type_) = type_ { - attrs.push(("type", type_)); - } - attrs - }, children), - Tag::Blockquote { style, children } => ("blockquote", match get_style_string(style) { - Some(style) => vec![("style", style)], - None => vec![], - }, children), + Tag::A { + href, + style, + type_, + children, + } => ( + "a", + { + let mut attrs = vec![]; + if let Some(href) = href { + attrs.push(("href", href)); + } + if let Some(style) = get_style_string(style) { + attrs.push(("style", style)); + } + if let Some(type_) = type_ { + attrs.push(("type", type_)); + } + attrs + }, + children, + ), + Tag::Blockquote { style, children } => ( + "blockquote", + match get_style_string(style) { + Some(style) => vec![("style", style)], + None => vec![], + }, + children, + ), Tag::Br => ("br", vec![], vec![]), - Tag::Cite { style, children } => ("cite", match get_style_string(style) { - Some(style) => vec![("style", style)], - None => vec![], - }, children), + Tag::Cite { style, children } => ( + "cite", + match get_style_string(style) { + Some(style) => vec![("style", style)], + None => vec![], + }, + children, + ), Tag::Em { children } => ("em", vec![], children), Tag::Img { src, alt } => { let mut attrs = vec![]; @@ -312,29 +412,51 @@ impl From for Element { attrs.push(("alt", alt)); } ("img", attrs, vec![]) - }, - Tag::Li { style, children } => ("li", match get_style_string(style) { - Some(style) => vec![("style", style)], - None => vec![], - }, children), - Tag::Ol { style, children } => ("ol", match get_style_string(style) { - Some(style) => vec![("style", style)], - None => vec![], - }, children), - Tag::P { style, children } => ("p", match get_style_string(style) { - Some(style) => vec![("style", style)], - None => vec![], - }, children), - Tag::Span { style, children } => ("span", match get_style_string(style) { - Some(style) => vec![("style", style)], - None => vec![], - }, children), + } + Tag::Li { style, children } => ( + "li", + match get_style_string(style) { + Some(style) => vec![("style", style)], + None => vec![], + }, + children, + ), + Tag::Ol { style, children } => ( + "ol", + match get_style_string(style) { + Some(style) => vec![("style", style)], + None => vec![], + }, + children, + ), + Tag::P { style, children } => ( + "p", + match get_style_string(style) { + Some(style) => vec![("style", style)], + None => vec![], + }, + children, + ), + Tag::Span { style, children } => ( + "span", + match get_style_string(style) { + Some(style) => vec![("style", style)], + None => vec![], + }, + children, + ), Tag::Strong { children } => ("strong", vec![], children), - Tag::Ul { style, children } => ("ul", match get_style_string(style) { - Some(style) => vec![("style", style)], - None => vec![], - }, children), - Tag::Unknown(_) => panic!("No unknown element should be present in XHTML-IM after parsing."), + Tag::Ul { style, children } => ( + "ul", + match get_style_string(style) { + Some(style) => vec![("style", style)], + None => vec![], + }, + children, + ), + Tag::Unknown(_) => { + panic!("No unknown element should be present in XHTML-IM after parsing.") + } }; let mut builder = Element::builder(name) .ns(ns::XHTML) @@ -354,7 +476,11 @@ fn children_to_nodes(children: Vec) -> impl IntoIterator { } fn children_to_html(children: Vec) -> String { - children.into_iter().map(|child| child.to_html()).collect::>().concat() + children + .into_iter() + .map(|child| child.to_html()) + .collect::>() + .concat() } fn write_attr(attr: Option, name: &str) -> String { @@ -369,7 +495,10 @@ fn parse_css(style: Option<&str>) -> Css { if let Some(style) = style { // TODO: make that parser a bit more resilient to things. for part in style.split(";") { - let mut part = part.splitn(2, ":").map(|a| a.to_string()).collect::>(); + let mut part = part + .splitn(2, ":") + .map(|a| a.to_string()) + .collect::>(); let key = part.pop().unwrap(); let value = part.pop().unwrap(); properties.push(Property { key, value }); @@ -457,7 +586,7 @@ mod tests { assert_eq!(style.len(), 0); assert_eq!(children.len(), 1); children - }, + } _ => panic!(), }; let text = match children.pop() { @@ -502,14 +631,19 @@ mod tests { fn generate_tree() { let world = "world".to_string(); - Body { style: vec![], xml_lang: Some("en".to_string()), children: vec![ - Child::Tag(Tag::P { style: vec![], children: vec![ - Child::Text("Hello ".to_string()), - Child::Tag(Tag::Strong { children: vec![ - Child::Text(world), - ] }), - Child::Text("!".to_string()), - ] }), - ] }; + Body { + style: vec![], + xml_lang: Some("en".to_string()), + children: vec![Child::Tag(Tag::P { + style: vec![], + children: vec![ + Child::Text("Hello ".to_string()), + Child::Tag(Tag::Strong { + children: vec![Child::Text(world)], + }), + Child::Text("!".to_string()), + ], + })], + }; } } diff --git a/xmpp-rs/examples/hello_bot.rs b/xmpp-rs/examples/hello_bot.rs index 7d13ba0a06dd73c01b4cc4fafdbda05730a1f1fa..42ad0d1475e39d426632640e3069e212b0da5b21 100644 --- a/xmpp-rs/examples/hello_bot.rs +++ b/xmpp-rs/examples/hello_bot.rs @@ -8,8 +8,8 @@ use futures::prelude::*; use std::env::args; use std::process::exit; use tokio::runtime::current_thread::Runtime; +use xmpp::{ClientBuilder, ClientFeature, ClientType, Event}; use xmpp_parsers::{message::MessageType, Jid}; -use xmpp::{ClientBuilder, ClientType, ClientFeature, Event}; fn main() { let args: Vec = args().collect(); @@ -40,40 +40,46 @@ fn main() { match evt { Event::Online => { println!("Online."); - }, + } Event::Disconnected => { println!("Disconnected."); return Err(None); - }, + } Event::ContactAdded(contact) => { println!("Contact {} added.", contact.jid); - }, + } Event::ContactRemoved(contact) => { println!("Contact {} removed.", contact.jid); - }, + } Event::ContactChanged(contact) => { println!("Contact {} changed.", contact.jid); - }, + } Event::JoinRoom(jid, conference) => { println!("Joining room {} ({:?})…", jid, conference.name); - agent.join_room(jid, conference.nick, conference.password, "en", "Yet another bot!"); - }, + agent.join_room( + jid, + conference.nick, + conference.password, + "en", + "Yet another bot!", + ); + } Event::LeaveRoom(jid) => { println!("Leaving room {}…", jid); - }, + } Event::LeaveAllRooms => { println!("Leaving all rooms…"); - }, + } Event::RoomJoined(jid) => { println!("Joined room {}.", jid); agent.send_message(Jid::Bare(jid), MessageType::Groupchat, "en", "Hello world!"); - }, + } Event::RoomLeft(jid) => { println!("Left room {}.", jid); - }, + } Event::AvatarRetrieved(jid, path) => { println!("Received avatar for {} in {}.", jid, path); - }, + } } Ok(()) }); diff --git a/xmpp-rs/src/lib.rs b/xmpp-rs/src/lib.rs index 71d2ee96f1e00d33b1bce0d587f5617b338d10cd..ee0277ff5e28ead880841dec468bfc53aa0a3c1e 100644 --- a/xmpp-rs/src/lib.rs +++ b/xmpp-rs/src/lib.rs @@ -6,33 +6,29 @@ #![deny(bare_trait_objects)] -use std::str::FromStr; -use std::rc::Rc; +use futures::{sync::mpsc, Future, Sink, Stream}; use std::cell::RefCell; use std::convert::TryFrom; -use futures::{Future,Stream, Sink, sync::mpsc}; -use tokio_xmpp::{ - Client as TokioXmppClient, - Event as TokioXmppEvent, - Packet, -}; +use std::rc::Rc; +use std::str::FromStr; +use tokio_xmpp::{Client as TokioXmppClient, Event as TokioXmppEvent, Packet}; use xmpp_parsers::{ bookmarks2::Conference, caps::{compute_disco, hash_caps, Caps}, disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity}, hashes::Algo, iq::{Iq, IqType}, - message::{Message, MessageType, Body}, + message::{Body, Message, MessageType}, muc::{ - Muc, user::{MucUser, Status}, + Muc, }, ns, presence::{Presence, Type as PresenceType}, - pubsub::pubsub::{PubSub, Items}, - roster::{Roster, Item as RosterItem}, - stanza_error::{StanzaError, ErrorType, DefinedCondition}, - Jid, BareJid, FullJid, JidParseError, + pubsub::pubsub::{Items, PubSub}, + roster::{Item as RosterItem, Roster}, + stanza_error::{DefinedCondition, ErrorType, StanzaError}, + BareJid, FullJid, Jid, JidParseError, }; #[macro_use] extern crate log; @@ -55,12 +51,10 @@ impl Default for ClientType { impl ToString for ClientType { fn to_string(&self) -> String { - String::from( - match self { - ClientType::Bot => "bot", - ClientType::Pc => "pc", - } - ) + String::from(match self { + ClientType::Bot => "bot", + ClientType::Pc => "pc", + }) } } @@ -131,11 +125,13 @@ impl ClientBuilder<'_> { } fn make_disco(&self) -> DiscoInfoResult { - let identities = vec![Identity::new("client", self.disco.0.to_string(), - "en", self.disco.1.to_string())]; - let mut features = vec![ - Feature::new(ns::DISCO_INFO), - ]; + let identities = vec![Identity::new( + "client", + self.disco.0.to_string(), + "en", + self.disco.1.to_string(), + )]; + let mut features = vec![Feature::new(ns::DISCO_INFO)]; #[cfg(feature = "avatars")] { if self.features.contains(&ClientFeature::Avatars) { @@ -180,7 +176,7 @@ impl ClientBuilder<'_> { ) -> Result<(Agent, impl Stream), JidParseError> where S: Stream - + Sink, + + Sink, { let disco = self.make_disco(); let node = self.website; @@ -191,115 +187,151 @@ impl ClientBuilder<'_> { let reader = { let mut sender_tx = sender_tx.clone(); let jid = self.jid.to_owned(); - stream.map(move |event| { - // Helper function to send an iq error. - let mut events = Vec::new(); - let send_error = |to, id, type_, condition, text: &str| { - let error = StanzaError::new(type_, condition, "en", text); - let iq = Iq::from_error(id, error) - .with_to(to) - .into(); - sender_tx.unbounded_send(Packet::Stanza(iq)).unwrap(); - }; - - match event { - TokioXmppEvent::Online(_) => { - let presence = ClientBuilder::make_initial_presence(&disco, &node).into(); - let packet = Packet::Stanza(presence); - sender_tx.unbounded_send(packet) - .unwrap(); - events.push(Event::Online); - // TODO: only send this when the ContactList feature is enabled. - let iq = Iq::from_get("roster", Roster { ver: None, items: vec![] }) - .into(); + stream + .map(move |event| { + // Helper function to send an iq error. + let mut events = Vec::new(); + let send_error = |to, id, type_, condition, text: &str| { + let error = StanzaError::new(type_, condition, "en", text); + let iq = Iq::from_error(id, error).with_to(to).into(); sender_tx.unbounded_send(Packet::Stanza(iq)).unwrap(); - // TODO: only send this when the JoinRooms feature is enabled. - let iq = Iq::from_get("bookmarks", PubSub::Items(Items::new(ns::BOOKMARKS2))) + }; + + match event { + TokioXmppEvent::Online(_) => { + let presence = + ClientBuilder::make_initial_presence(&disco, &node).into(); + let packet = Packet::Stanza(presence); + sender_tx.unbounded_send(packet).unwrap(); + events.push(Event::Online); + // TODO: only send this when the ContactList feature is enabled. + let iq = Iq::from_get( + "roster", + Roster { + ver: None, + items: vec![], + }, + ) .into(); - sender_tx.unbounded_send(Packet::Stanza(iq)).unwrap(); - } - TokioXmppEvent::Disconnected => { - events.push(Event::Disconnected); - } - TokioXmppEvent::Stanza(stanza) => { - if stanza.is("iq", "jabber:client") { - let iq = Iq::try_from(stanza).unwrap(); - let from = - iq.from.clone().unwrap_or_else(|| Jid::from_str(&jid).unwrap()); - if let IqType::Get(payload) = iq.payload { - if payload.is("query", ns::DISCO_INFO) { - let query = DiscoInfoQuery::try_from(payload); - match query { - Ok(query) => { - let mut disco_info = disco.clone(); - disco_info.node = query.node; - let iq = Iq::from_result(iq.id, Some(disco_info)) - .with_to(iq.from.unwrap()) - .into(); - sender_tx.unbounded_send(Packet::Stanza(iq)).unwrap(); - }, - Err(err) => { - send_error(iq.from.unwrap(), iq.id, ErrorType::Modify, DefinedCondition::BadRequest, &format!("{}", err)); - }, + sender_tx.unbounded_send(Packet::Stanza(iq)).unwrap(); + // TODO: only send this when the JoinRooms feature is enabled. + let iq = Iq::from_get( + "bookmarks", + PubSub::Items(Items::new(ns::BOOKMARKS2)), + ) + .into(); + sender_tx.unbounded_send(Packet::Stanza(iq)).unwrap(); + } + TokioXmppEvent::Disconnected => { + events.push(Event::Disconnected); + } + TokioXmppEvent::Stanza(stanza) => { + if stanza.is("iq", "jabber:client") { + let iq = Iq::try_from(stanza).unwrap(); + let from = iq + .from + .clone() + .unwrap_or_else(|| Jid::from_str(&jid).unwrap()); + if let IqType::Get(payload) = iq.payload { + if payload.is("query", ns::DISCO_INFO) { + let query = DiscoInfoQuery::try_from(payload); + match query { + Ok(query) => { + let mut disco_info = disco.clone(); + disco_info.node = query.node; + let iq = Iq::from_result(iq.id, Some(disco_info)) + .with_to(iq.from.unwrap()) + .into(); + sender_tx + .unbounded_send(Packet::Stanza(iq)) + .unwrap(); + } + Err(err) => { + send_error( + iq.from.unwrap(), + iq.id, + ErrorType::Modify, + DefinedCondition::BadRequest, + &format!("{}", err), + ); + } + } + } else { + // We MUST answer unhandled get iqs with a service-unavailable error. + send_error( + iq.from.unwrap(), + iq.id, + ErrorType::Cancel, + DefinedCondition::ServiceUnavailable, + "No handler defined for this kind of iq.", + ); } - } else { - // We MUST answer unhandled get iqs with a service-unavailable error. - send_error(iq.from.unwrap(), iq.id, ErrorType::Cancel, DefinedCondition::ServiceUnavailable, "No handler defined for this kind of iq."); - } - } else if let IqType::Result(Some(payload)) = iq.payload { - // TODO: move private iqs like this one somewhere else, for - // security reasons. - if payload.is("query", ns::ROSTER) && iq.from.is_none() { - let roster = Roster::try_from(payload).unwrap(); - for item in roster.items.into_iter() { - events.push(Event::ContactAdded(item)); + } else if let IqType::Result(Some(payload)) = iq.payload { + // TODO: move private iqs like this one somewhere else, for + // security reasons. + if payload.is("query", ns::ROSTER) && iq.from.is_none() { + let roster = Roster::try_from(payload).unwrap(); + for item in roster.items.into_iter() { + events.push(Event::ContactAdded(item)); + } + } else if payload.is("pubsub", ns::PUBSUB) { + let new_events = pubsub::handle_iq_result(&from, payload); + events.extend(new_events); } - } else if payload.is("pubsub", ns::PUBSUB) { - let new_events = pubsub::handle_iq_result(&from, payload); - events.extend(new_events); + } else if let IqType::Set(_) = iq.payload { + // We MUST answer unhandled set iqs with a service-unavailable error. + send_error( + iq.from.unwrap(), + iq.id, + ErrorType::Cancel, + DefinedCondition::ServiceUnavailable, + "No handler defined for this kind of iq.", + ); } - } else if let IqType::Set(_) = iq.payload { - // We MUST answer unhandled set iqs with a service-unavailable error. - send_error(iq.from.unwrap(), iq.id, ErrorType::Cancel, DefinedCondition::ServiceUnavailable, "No handler defined for this kind of iq."); - } - } else if stanza.is("message", "jabber:client") { - let message = Message::try_from(stanza).unwrap(); - let from = message.from.clone().unwrap(); - for child in message.payloads { - if child.is("event", ns::PUBSUB_EVENT) { - let new_events = pubsub::handle_event(&from, child, &mut sender_tx); - events.extend(new_events); + } else if stanza.is("message", "jabber:client") { + let message = Message::try_from(stanza).unwrap(); + let from = message.from.clone().unwrap(); + for child in message.payloads { + if child.is("event", ns::PUBSUB_EVENT) { + let new_events = + pubsub::handle_event(&from, child, &mut sender_tx); + events.extend(new_events); + } } - } - } else if stanza.is("presence", "jabber:client") { - let presence = Presence::try_from(stanza).unwrap(); - let from: BareJid = match presence.from.clone().unwrap() { - Jid::Full(FullJid { node, domain, .. }) => BareJid { node, domain }, - Jid::Bare(bare) => bare, - }; - for payload in presence.payloads.into_iter() { - let muc_user = match MucUser::try_from(payload) { - Ok(muc_user) => muc_user, - _ => continue + } else if stanza.is("presence", "jabber:client") { + let presence = Presence::try_from(stanza).unwrap(); + let from: BareJid = match presence.from.clone().unwrap() { + Jid::Full(FullJid { node, domain, .. }) => { + BareJid { node, domain } + } + Jid::Bare(bare) => bare, }; - for status in muc_user.status.into_iter() { - if status == Status::SelfPresence { - events.push(Event::RoomJoined(from.clone())); - break; + for payload in presence.payloads.into_iter() { + let muc_user = match MucUser::try_from(payload) { + Ok(muc_user) => muc_user, + _ => continue, + }; + for status in muc_user.status.into_iter() { + if status == Status::SelfPresence { + events.push(Event::RoomJoined(from.clone())); + break; + } } } + } else if stanza.is("error", "http://etherx.jabber.org/streams") { + println!( + "Received a fatal stream error: {}", + String::from(&stanza) + ); + } else { + panic!("Unknown stanza: {}", String::from(&stanza)); } - } else if stanza.is("error", "http://etherx.jabber.org/streams") { - println!("Received a fatal stream error: {}", String::from(&stanza)); - } else { - panic!("Unknown stanza: {}", String::from(&stanza)); } } - } - futures::stream::iter_ok(events) - }) - .flatten() + futures::stream::iter_ok(events) + }) + .flatten() }; let sender = sender_rx @@ -335,8 +367,14 @@ pub struct Agent { } impl Agent { - pub fn join_room(&mut self, room: BareJid, nick: Option, password: Option, - lang: &str, status: &str) { + pub fn join_room( + &mut self, + room: BareJid, + nick: Option, + password: Option, + lang: &str, + status: &str, + ) { let mut muc = Muc::new(); if let Some(password) = password { muc = muc.with_password(password); @@ -344,32 +382,35 @@ impl Agent { let nick = nick.unwrap_or_else(|| self.default_nick.borrow().clone()); let room_jid = room.with_resource(nick); - let mut presence = Presence::new(PresenceType::None) - .with_to(Jid::Full(room_jid)); + let mut presence = Presence::new(PresenceType::None).with_to(Jid::Full(room_jid)); presence.add_payload(muc); presence.set_status(String::from(lang), String::from(status)); let presence = presence.into(); - self.sender_tx.unbounded_send(Packet::Stanza(presence)) + self.sender_tx + .unbounded_send(Packet::Stanza(presence)) .unwrap(); } pub fn send_message(&mut self, recipient: Jid, type_: MessageType, lang: &str, text: &str) { let mut message = Message::new(Some(recipient)); message.type_ = type_; - message.bodies.insert(String::from(lang), Body(String::from(text))); + message + .bodies + .insert(String::from(lang), Body(String::from(text))); let message = message.into(); - self.sender_tx.unbounded_send(Packet::Stanza(message)) + self.sender_tx + .unbounded_send(Packet::Stanza(message)) .unwrap(); } } #[cfg(test)] mod tests { + use super::{Agent, ClientBuilder, ClientFeature, ClientType, Event}; use futures::prelude::*; - use tokio_xmpp::Client as TokioXmppClient; - use tokio::runtime::current_thread::Runtime; - use super::{Agent, ClientBuilder, ClientType, ClientFeature, Event}; use futures::sync::mpsc; + use tokio::runtime::current_thread::Runtime; + use tokio_xmpp::Client as TokioXmppClient; #[test] fn test_simple() { @@ -386,8 +427,7 @@ mod tests { .enable_feature(ClientFeature::Avatars) .enable_feature(ClientFeature::ContactList); - let (_agent, stream): (Agent, _) = - client_builder + let (_agent, stream): (Agent, _) = client_builder .build_impl(client, sender_tx.clone(), sender_rx) .unwrap(); diff --git a/xmpp-rs/src/pubsub/avatar.rs b/xmpp-rs/src/pubsub/avatar.rs index 1b95b762c40e31a66f1f0d90129e6f182c42567b..1a8627a8260031243eab54e92c7701dd23e8441e 100644 --- a/xmpp-rs/src/pubsub/avatar.rs +++ b/xmpp-rs/src/pubsub/avatar.rs @@ -12,6 +12,7 @@ use std::io::{self, Write}; use tokio_xmpp::Packet; use xmpp_parsers::{ avatar::{Data, Metadata}, + hashes::Hash, iq::Iq, ns, pubsub::{ @@ -19,7 +20,6 @@ use xmpp_parsers::{ pubsub::{Items, PubSub}, NodeName, }, - hashes::Hash, Jid, }; @@ -32,7 +32,11 @@ fn hash_to_hex(hash: &Hash) -> String { bytes.join("") } -pub(crate) fn handle_metadata_pubsub_event(from: &Jid, tx: &mut mpsc::UnboundedSender, items: Vec) -> impl IntoIterator { +pub(crate) fn handle_metadata_pubsub_event( + from: &Jid, + tx: &mut mpsc::UnboundedSender, + items: Vec, +) -> impl IntoIterator { let mut events = Vec::new(); for item in items { let payload = item.payload.clone().unwrap(); @@ -58,12 +62,15 @@ pub(crate) fn handle_metadata_pubsub_event(from: &Jid, tx: &mut mpsc::UnboundedS } fn download_avatar(from: &Jid) -> Iq { - Iq::from_get("coucou", PubSub::Items(Items { - max_items: None, - node: NodeName(String::from(ns::AVATAR_DATA)), - subid: None, - items: Vec::new(), - })) + Iq::from_get( + "coucou", + PubSub::Items(Items { + max_items: None, + node: NodeName(String::from(ns::AVATAR_DATA)), + subid: None, + items: Vec::new(), + }), + ) .with_to(from.clone()) } diff --git a/xmpp-rs/src/pubsub/mod.rs b/xmpp-rs/src/pubsub/mod.rs index c4736563e48c7616ee511cbdc45af4d5a210579d..f7cb91e7e0718aaf1c22cddff49830f7e132842f 100644 --- a/xmpp-rs/src/pubsub/mod.rs +++ b/xmpp-rs/src/pubsub/mod.rs @@ -10,21 +10,21 @@ use std::convert::TryFrom; use std::str::FromStr; use tokio_xmpp::Packet; use xmpp_parsers::{ - Jid, BareJid, - Element, + bookmarks2::{Autojoin, Conference}, ns, - bookmarks2::{ - Autojoin, - Conference, - }, pubsub::event::PubSubEvent, pubsub::pubsub::PubSub, + BareJid, Element, Jid, }; #[cfg(feature = "avatars")] pub(crate) mod avatar; -pub(crate) fn handle_event(from: &Jid, elem: Element, mut tx: &mut mpsc::UnboundedSender) -> impl IntoIterator { +pub(crate) fn handle_event( + from: &Jid, + elem: Element, + mut tx: &mut mpsc::UnboundedSender, +) -> impl IntoIterator { let mut events = Vec::new(); let event = PubSubEvent::try_from(elem); trace!("PubSub event: {:#?}", event); @@ -35,7 +35,7 @@ pub(crate) fn handle_event(from: &Jid, elem: Element, mut tx: &mut mpsc::Unbound ref node if node == ns::AVATAR_METADATA => { let new_events = avatar::handle_metadata_pubsub_event(&from, &mut tx, items); events.extend(new_events); - }, + } ref node if node == ns::BOOKMARKS2 => { // TODO: Check that our bare JID is the sender. assert_eq!(items.len(), 1); @@ -49,11 +49,11 @@ pub(crate) fn handle_event(from: &Jid, elem: Element, mut tx: &mut mpsc::Unbound } else { events.push(Event::LeaveRoom(jid)); } - }, - Err(err) => println!("not bookmark: {}", err) + } + Err(err) => println!("not bookmark: {}", err), } - }, - ref node => unimplemented!("node {}", node) + } + ref node => unimplemented!("node {}", node), } } Ok(PubSubEvent::RetractedItems { node, items }) => { @@ -64,8 +64,8 @@ pub(crate) fn handle_event(from: &Jid, elem: Element, mut tx: &mut mpsc::Unbound let item = items.clone().pop().unwrap(); let jid = BareJid::from_str(&item.0).unwrap(); events.push(Event::LeaveRoom(jid)); - }, - ref node => unimplemented!("node {}", node) + } + ref node => unimplemented!("node {}", node), } } Ok(PubSubEvent::Purge { node }) => { @@ -73,11 +73,11 @@ pub(crate) fn handle_event(from: &Jid, elem: Element, mut tx: &mut mpsc::Unbound ref node if node == ns::BOOKMARKS2 => { // TODO: Check that our bare JID is the sender. events.push(Event::LeaveAllRooms); - }, - ref node => unimplemented!("node {}", node) + } + ref node => unimplemented!("node {}", node), } } - _ => unimplemented!() + _ => unimplemented!(), } events } @@ -92,7 +92,7 @@ pub(crate) fn handle_iq_result(from: &Jid, elem: Element) -> impl IntoIterator { let new_events = avatar::handle_data_pubsub_iq(&from, &items); events.extend(new_events); - }, + } ref node if node == ns::BOOKMARKS2 => { events.push(Event::LeaveAllRooms); for item in items.items { @@ -104,12 +104,12 @@ pub(crate) fn handle_iq_result(from: &Jid, elem: Element) -> impl IntoIterator panic!("Wrong payload type in bookmarks 2 item: {}", err), } } - }, - _ => unimplemented!() + } + _ => unimplemented!(), } } events