Rustfmt pass, and rustfmt --check in CI"
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
e1b53eae3c
commit
a104ebc3f6
79 changed files with 1344 additions and 957 deletions
|
|
@ -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<Caps, String> {
|
||||
|
|
|
|||
|
|
@ -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<BindQuery> 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<Element> 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 = "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>Hello™</resource></bind>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let elem: Element =
|
||||
"<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>Hello™</resource></bind>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let bind = BindQuery::try_from(elem).unwrap();
|
||||
// FIXME: “™” should be resourceprep’d into “TM” here…
|
||||
//assert_eq!(bind.resource.unwrap(), "HelloTM");
|
||||
|
|
|
|||
|
|
@ -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!(
|
||||
|
|
|
|||
|
|
@ -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 = "<data xmlns='urn:xmpp:bob' cid='sha1+8f35fef110ffc5df08d579a50083ff9308fb6242@bob.xmpp.org'/>".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::<ContentId>().unwrap_err();
|
||||
let error = "sha1+1234@coucou.linkmauve.fr"
|
||||
.parse::<ContentId>()
|
||||
.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::<ContentId>().unwrap_err();
|
||||
let error = "sha1+invalid@bob.xmpp.org"
|
||||
.parse::<ContentId>()
|
||||
.unwrap_err();
|
||||
let message = match error {
|
||||
Error::ParseIntError(error) => error,
|
||||
_ => panic!(),
|
||||
|
|
|
|||
|
|
@ -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 = "<conference xmlns='urn:xmpp:bookmarks:0'/>".parse().unwrap();
|
||||
let elem: Element = "<conference xmlns='urn:xmpp:bookmarks:0'/>"
|
||||
.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);
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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 = "<disable xmlns='urn:xmpp:saslcert:1'><name>Mobile Client</name></disable>".parse().unwrap();
|
||||
let elem: Element =
|
||||
"<disable xmlns='urn:xmpp:saslcert:1'><name>Mobile Client</name></disable>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let disable = Disable::try_from(elem).unwrap();
|
||||
assert_eq!(disable.name.0, "Mobile Client");
|
||||
|
||||
let elem: Element = "<revoke xmlns='urn:xmpp:saslcert:1'><name>Mobile Client</name></revoke>".parse().unwrap();
|
||||
let elem: Element =
|
||||
"<revoke xmlns='urn:xmpp:saslcert:1'><name>Mobile Client</name></revoke>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let revoke = Revoke::try_from(elem).unwrap();
|
||||
assert_eq!(revoke.name.0, "Mobile Client");
|
||||
}
|
||||
|
|
@ -177,7 +189,9 @@ mod tests {
|
|||
<name>Laptop</name>
|
||||
<x509cert>BBBB</x509cert>
|
||||
</item>
|
||||
</items>"#.parse().unwrap();
|
||||
</items>"#
|
||||
.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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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<Field> 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<DataForm> 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()
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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 `<feature/>` with the according `@var`.
|
||||
pub fn new<S: Into<String>>(var: S) -> Feature {
|
||||
Feature {
|
||||
var: var.into(),
|
||||
}
|
||||
Feature { var: var.into() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -66,10 +64,11 @@ generate_element!(
|
|||
impl Identity {
|
||||
/// Create a new `<identity/>`.
|
||||
pub fn new<C, T, L, N>(category: C, type_: T, lang: L, name: N) -> Identity
|
||||
where C: Into<String>,
|
||||
T: Into<String>,
|
||||
L: Into<String>,
|
||||
N: Into<String>,
|
||||
where
|
||||
C: Into<String>,
|
||||
T: Into<String>,
|
||||
L: Into<String>,
|
||||
N: Into<String>,
|
||||
{
|
||||
Identity {
|
||||
category: category.into(),
|
||||
|
|
@ -81,8 +80,9 @@ impl Identity {
|
|||
|
||||
/// Create a new `<identity/>` without a name.
|
||||
pub fn new_anonymous<C, T, L, N>(category: C, type_: T) -> Identity
|
||||
where C: Into<String>,
|
||||
T: Into<String>,
|
||||
where
|
||||
C: Into<String>,
|
||||
T: Into<String>,
|
||||
{
|
||||
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 = "<query xmlns='http://jabber.org/protocol/disco#info'><identity category='coucou'/></query>".parse().unwrap();
|
||||
let error = DiscoInfoResult::try_from(elem).unwrap_err();
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ impl PresencePayload for ECaps2 {}
|
|||
impl ECaps2 {
|
||||
/// Create an ECaps2 element from a list of hashes.
|
||||
pub fn new(hashes: Vec<Hash>) -> ECaps2 {
|
||||
ECaps2 {
|
||||
hashes,
|
||||
}
|
||||
ECaps2 { hashes }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +83,13 @@ fn compute_extensions(extensions: &[DataForm]) -> Result<Vec<u8>, ()> {
|
|||
}
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -236,8 +236,14 @@ mod tests {
|
|||
fn value_serialisation() {
|
||||
let elem: Element = "<hash xmlns='urn:xmpp:hashes:2' algo='sha-256'>2XarmwTlNxDAMkvymloX3S5+VbylNrJt/l5QyPa+YoU=</hash>".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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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<Query> 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))
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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<Iq> 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 = "<iq xmlns='jabber:client' id='coucou'/>".parse().unwrap();
|
||||
#[cfg(feature = "component")]
|
||||
let elem: Element = "<iq xmlns='jabber:component:accept' id='coucou'/>".parse().unwrap();
|
||||
let elem: Element = "<iq xmlns='jabber:component:accept' id='coucou'/>"
|
||||
.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 = "<iq xmlns='jabber:client' type='result' id='res'/>".parse().unwrap();
|
||||
let elem: Element = "<iq xmlns='jabber:client' type='result' id='res'/>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
#[cfg(feature = "component")]
|
||||
let elem: Element = "<iq xmlns='jabber:component:accept' type='result' id='res'/>"
|
||||
.parse()
|
||||
|
|
@ -416,7 +420,9 @@ mod tests {
|
|||
#[test]
|
||||
fn test_serialise() {
|
||||
#[cfg(not(feature = "component"))]
|
||||
let elem: Element = "<iq xmlns='jabber:client' type='result' id='res'/>".parse().unwrap();
|
||||
let elem: Element = "<iq xmlns='jabber:client' type='result' id='res'/>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
#[cfg(feature = "component")]
|
||||
let elem: Element = "<iq xmlns='jabber:component:accept' type='result' id='res'/>"
|
||||
.parse()
|
||||
|
|
|
|||
|
|
@ -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<J: Into<String>>(jid: J) -> JidPrepQuery {
|
||||
JidPrepQuery {
|
||||
data: jid.into(),
|
||||
}
|
||||
JidPrepQuery { data: jid.into() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -62,12 +60,19 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn simple() {
|
||||
let elem: Element = "<jid xmlns='urn:xmpp:jidprep:0'>ROMeo@montague.lit/orchard</jid>".parse().unwrap();
|
||||
let elem: Element = "<jid xmlns='urn:xmpp:jidprep:0'>ROMeo@montague.lit/orchard</jid>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let query = JidPrepQuery::try_from(elem).unwrap();
|
||||
assert_eq!(query.data, "ROMeo@montague.lit/orchard");
|
||||
|
||||
let elem: Element = "<jid xmlns='urn:xmpp:jidprep:0'>romeo@montague.lit/orchard</jid>".parse().unwrap();
|
||||
let elem: Element = "<jid xmlns='urn:xmpp:jidprep:0'>romeo@montague.lit/orchard</jid>"
|
||||
.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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Reason> for Element {
|
|||
Reason::UnsupportedApplications => "unsupported-applications",
|
||||
Reason::UnsupportedTransports => "unsupported-transports",
|
||||
})
|
||||
.ns(ns::JINGLE)
|
||||
.build()
|
||||
.ns(ns::JINGLE)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -521,13 +521,8 @@ impl TryFrom<Element> 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<ReasonElement> 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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Fingerprint, Error> {
|
||||
pub fn from_colon_separated_hex(
|
||||
setup: Setup,
|
||||
algo: &str,
|
||||
hash: &str,
|
||||
) -> Result<Fingerprint, Error> {
|
||||
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
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<File> 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()
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn parse_simple() {
|
||||
let elem: Element = "<rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='nack' subtype='sli'/>"
|
||||
let elem: Element =
|
||||
"<rtcp-fb xmlns='urn:xmpp:jingle:apps:rtp:rtcp-fb:0' type='nack' subtype='sli'/>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let rtcp_fb = RtcpFb::try_from(elem).unwrap();
|
||||
|
|
|
|||
|
|
@ -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!(
|
||||
|
|
|
|||
|
|
@ -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<Transport> 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()
|
||||
|
|
|
|||
|
|
@ -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 {
|
|||
<source ssrc='2301230316'/>
|
||||
<source ssrc='386328120'/>
|
||||
</ssrc-group>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
.parse()
|
||||
.unwrap();
|
||||
let mut group = Group::try_from(elem).unwrap();
|
||||
assert_eq!(group.semantics, "FID");
|
||||
assert_eq!(group.sources.len(), 2);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<Jid>) -> ::std::option::IntoIter<Nod
|
|||
Some(
|
||||
Element::builder(name)
|
||||
.ns(ns::MAM)
|
||||
.append_all(
|
||||
jids.into_iter()
|
||||
.map(|jid|
|
||||
Element::builder("jid")
|
||||
.ns(ns::MAM)
|
||||
.append(String::from(jid))))
|
||||
.append_all(jids.into_iter().map(|jid| {
|
||||
Element::builder("jid")
|
||||
.ns(ns::MAM)
|
||||
.append(String::from(jid))
|
||||
}))
|
||||
.into(),
|
||||
).into_iter()
|
||||
)
|
||||
.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ mod tests {
|
|||
use crate::data_forms::DataForm;
|
||||
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]
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@
|
|||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
use crate::util::error::Error;
|
||||
use crate::ns;
|
||||
use jid::Jid;
|
||||
use crate::util::error::Error;
|
||||
use crate::Element;
|
||||
use jid::Jid;
|
||||
use std::collections::BTreeMap;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
|
|
@ -212,38 +212,28 @@ impl From<Message> 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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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<Element> 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)),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_invalid_id() {
|
||||
let elem: Element = "<occupant-id xmlns='urn:xmpp:occupant-id:0'/>".parse().unwrap();
|
||||
let elem: Element = "<occupant-id xmlns='urn:xmpp:occupant-id:0'/>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let error = OccupantId::try_from(elem).unwrap_err();
|
||||
let message = match error {
|
||||
Error::ParseError(string) => string,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 `<presence/>`.
|
||||
pub trait PresencePayload: TryFrom<Element> + Into<Element> {}
|
||||
|
|
@ -232,8 +232,9 @@ impl Presence {
|
|||
|
||||
/// Set the availability information of this presence.
|
||||
pub fn set_status<L, S>(&mut self, lang: L, status: S)
|
||||
where L: Into<Lang>,
|
||||
S: Into<Status>,
|
||||
where
|
||||
L: Into<Lang>,
|
||||
S: Into<Status>,
|
||||
{
|
||||
self.statuses.insert(lang.into(), status.into());
|
||||
}
|
||||
|
|
@ -310,27 +311,21 @@ impl From<Presence> 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 = "<presence xmlns='jabber:client'/>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let elem: Element = "<presence xmlns='jabber:client'/>".parse().unwrap();
|
||||
#[cfg(feature = "component")]
|
||||
let elem: Element = "<presence xmlns='jabber:component:accept'/>"
|
||||
.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"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 `<item/>`.
|
||||
|
|
@ -214,15 +214,11 @@ impl From<PubSubEvent> 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),
|
||||
|
|
|
|||
|
|
@ -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<P: PubSubPayload>(id: Option<ItemId>, publisher: Option<Jid>, payload: Option<P>) -> Item {
|
||||
pub fn new<P: PubSubPayload>(
|
||||
id: Option<ItemId>,
|
||||
publisher: Option<Jid>,
|
||||
payload: Option<P>,
|
||||
) -> Item {
|
||||
Item {
|
||||
id,
|
||||
publisher,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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<SetQuery> 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)
|
||||
|
|
|
|||
|
|
@ -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<Failure> 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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 `<error/>` with the according content.
|
||||
pub fn new<L, T>(type_: ErrorType, defined_condition: DefinedCondition, lang: L, text: T) -> StanzaError
|
||||
where L: Into<Lang>,
|
||||
T: Into<String>,
|
||||
pub fn new<L, T>(
|
||||
type_: ErrorType,
|
||||
defined_condition: DefinedCondition,
|
||||
lang: L,
|
||||
text: T,
|
||||
) -> StanzaError
|
||||
where
|
||||
L: Into<Lang>,
|
||||
T: Into<String>,
|
||||
{
|
||||
StanzaError {
|
||||
type_,
|
||||
|
|
@ -294,14 +300,12 @@ impl From<StanzaError> 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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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<Element> 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<TimeResult> 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,10 @@ pub struct WhitespaceAwareBase64;
|
|||
|
||||
impl WhitespaceAwareBase64 {
|
||||
pub fn decode(s: &str) -> Result<Vec<u8>, 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)?)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Element> 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<Element> 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<Body> for Element {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Tag {
|
||||
A { href: Option<String>, style: Css, type_: Option<String>, children: Vec<Child> },
|
||||
Blockquote { style: Css, children: Vec<Child> },
|
||||
A {
|
||||
href: Option<String>,
|
||||
style: Css,
|
||||
type_: Option<String>,
|
||||
children: Vec<Child>,
|
||||
},
|
||||
Blockquote {
|
||||
style: Css,
|
||||
children: Vec<Child>,
|
||||
},
|
||||
Br,
|
||||
Cite { style: Css, children: Vec<Child> },
|
||||
Em { children: Vec<Child> },
|
||||
Img { src: Option<String>, alt: Option<String> }, // TODO: height, width, style
|
||||
Li { style: Css, children: Vec<Child> },
|
||||
Ol { style: Css, children: Vec<Child> },
|
||||
P { style: Css, children: Vec<Child> },
|
||||
Span { style: Css, children: Vec<Child> },
|
||||
Strong { children: Vec<Child> },
|
||||
Ul { style: Css, children: Vec<Child> },
|
||||
Cite {
|
||||
style: Css,
|
||||
children: Vec<Child>,
|
||||
},
|
||||
Em {
|
||||
children: Vec<Child>,
|
||||
},
|
||||
Img {
|
||||
src: Option<String>,
|
||||
alt: Option<String>,
|
||||
}, // TODO: height, width, style
|
||||
Li {
|
||||
style: Css,
|
||||
children: Vec<Child>,
|
||||
},
|
||||
Ol {
|
||||
style: Css,
|
||||
children: Vec<Child>,
|
||||
},
|
||||
P {
|
||||
style: Css,
|
||||
children: Vec<Child>,
|
||||
},
|
||||
Span {
|
||||
style: Css,
|
||||
children: Vec<Child>,
|
||||
},
|
||||
Strong {
|
||||
children: Vec<Child>,
|
||||
},
|
||||
Ul {
|
||||
style: Css,
|
||||
children: Vec<Child>,
|
||||
},
|
||||
Unknown(Vec<Child>),
|
||||
}
|
||||
|
||||
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!("<a{}{}{}>{}</a>", href, style, type_, children_to_html(children))
|
||||
},
|
||||
format!(
|
||||
"<a{}{}{}>{}</a>",
|
||||
href,
|
||||
style,
|
||||
type_,
|
||||
children_to_html(children)
|
||||
)
|
||||
}
|
||||
Tag::Blockquote { style, children } => {
|
||||
let style = write_attr(get_style_string(style), "style");
|
||||
format!("<blockquote{}>{}</blockquote>", style, children_to_html(children))
|
||||
},
|
||||
format!(
|
||||
"<blockquote{}>{}</blockquote>",
|
||||
style,
|
||||
children_to_html(children)
|
||||
)
|
||||
}
|
||||
Tag::Br => String::from("<br>"),
|
||||
Tag::Cite { style, children } => {
|
||||
let style = write_attr(get_style_string(style), "style");
|
||||
format!("<cite{}>{}</cite>", style, children_to_html(children))
|
||||
},
|
||||
}
|
||||
Tag::Em { children } => format!("<em>{}</em>", 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!("<ul{}>{}</ul>", 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<Element> 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<Element> for Tag {
|
|||
impl From<Tag> 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<Tag> 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<Child>) -> impl IntoIterator<Item = Node> {
|
|||
}
|
||||
|
||||
fn children_to_html(children: Vec<Child>) -> String {
|
||||
children.into_iter().map(|child| child.to_html()).collect::<Vec<_>>().concat()
|
||||
children
|
||||
.into_iter()
|
||||
.map(|child| child.to_html())
|
||||
.collect::<Vec<_>>()
|
||||
.concat()
|
||||
}
|
||||
|
||||
fn write_attr(attr: Option<String>, 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::<Vec<_>>();
|
||||
let mut part = part
|
||||
.splitn(2, ":")
|
||||
.map(|a| a.to_string())
|
||||
.collect::<Vec<_>>();
|
||||
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()),
|
||||
],
|
||||
})],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue