diff --git a/parsers/ChangeLog b/parsers/ChangeLog index 120b5371..2c02f4bc 100644 --- a/parsers/ChangeLog +++ b/parsers/ChangeLog @@ -12,6 +12,8 @@ XXXX-YY-ZZ RELEASER used in XMPP. - Remove the unnecessary SaslMechanisms struct, to directly extract SASL mechanisms in a Vec in StreamFeatures. + - The type of disco::DiscoInfoResult::features changed from + Vec to Vec, this lets us remove Feature as well. - bind::BindFeature::required is now a bool, thanks to xso’s flag. - jingle_rtp::Description::rtcp_mux is now a bool flag too. - stream_limits::Limits now extract directly to NonZeroU32. diff --git a/parsers/src/caps.rs b/parsers/src/caps.rs index 5c1624b3..1e3804ea 100644 --- a/parsers/src/caps.rs +++ b/parsers/src/caps.rs @@ -7,7 +7,7 @@ use xso::{AsXml, FromXml}; use crate::data_forms::DataForm; -use crate::disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity}; +use crate::disco::{DiscoInfoQuery, DiscoInfoResult, Identity}; use crate::hashes::{Algo, Hash}; use crate::ns; use crate::presence::PresencePayload; @@ -79,8 +79,8 @@ fn compute_items Vec>(things: &[T], encode: F) -> Vec { string } -fn compute_features(features: &[Feature]) -> Vec { - compute_items(features, |feature| compute_item(&feature.var)) +fn compute_features(features: &[String]) -> Vec { + compute_items(features, |feature| compute_item(&feature)) } fn compute_identities(identities: &[Identity]) -> Vec { diff --git a/parsers/src/disco.rs b/parsers/src/disco.rs index 9ee4a5fb..bb9d2904 100644 --- a/parsers/src/disco.rs +++ b/parsers/src/disco.rs @@ -26,22 +26,6 @@ pub struct DiscoInfoQuery { impl IqGetPayload for DiscoInfoQuery {} -/// Structure representing a `` element. -#[derive(FromXml, AsXml, Debug, Clone, PartialEq, Eq, Hash)] -#[xml(namespace = ns::DISCO_INFO, name = "feature")] -pub struct Feature { - /// Namespace of the feature we want to represent. - #[xml(attribute)] - pub var: String, -} - -impl Feature { - /// Create a new `` with the according `@var`. - pub fn new>(var: S) -> Feature { - Feature { var: var.into() } - } -} - /// Structure representing an `` element. #[derive(FromXml, AsXml, Debug, Clone, PartialEq, Eq, Hash)] #[xml(namespace = ns::DISCO_INFO, name = "identity")] @@ -113,8 +97,8 @@ pub struct DiscoInfoResult { pub identities: Vec, /// List of features supported by this entity. - #[xml(child(n = ..))] - pub features: Vec, + #[xml(extract(n = .., name = "feature", fields(attribute(name = "var", type_ = String))))] + pub features: Vec, /// List of extensions reported by this entity. #[xml(child(n = ..))] @@ -192,7 +176,6 @@ mod tests { #[test] fn test_size() { assert_size!(Identity, 48); - assert_size!(Feature, 12); assert_size!(DiscoInfoQuery, 12); assert_size!(DiscoInfoResult, 48); @@ -205,7 +188,6 @@ mod tests { #[test] fn test_size() { assert_size!(Identity, 96); - assert_size!(Feature, 24); assert_size!(DiscoInfoQuery, 24); assert_size!(DiscoInfoResult, 96); @@ -325,9 +307,11 @@ mod tests { FromElementError::Invalid(Error::Other(string)) => string, _ => panic!(), }; + // TODO: Make xso generate a better error message, with s/unnamed field 0/'var'/ for + // instance. assert_eq!( message, - "Required attribute field 'var' on Feature element missing." + "Required attribute unnamed field 0 on extraction for field 'features' in DiscoInfoResult element missing." ); } diff --git a/parsers/src/ecaps2.rs b/parsers/src/ecaps2.rs index a2bb3048..d1a8c5cd 100644 --- a/parsers/src/ecaps2.rs +++ b/parsers/src/ecaps2.rs @@ -7,7 +7,7 @@ use xso::{AsXml, FromXml}; use crate::data_forms::DataForm; -use crate::disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity}; +use crate::disco::{DiscoInfoQuery, DiscoInfoResult, Identity}; use crate::hashes::{Algo, Hash}; use crate::ns; use crate::presence::PresencePayload; @@ -64,8 +64,8 @@ fn compute_items<'x, T: 'x, I: IntoIterator, F: Fn(&'x T) -> Vec Vec { - compute_items(features, 0x1c, |feature| compute_item(&feature.var)) +fn compute_features(features: &[String]) -> Vec { + compute_items(features, 0x1c, |feature| compute_item(&feature)) } fn compute_identities(identities: &[Identity]) -> Vec { diff --git a/tokio-xmpp/examples/download_avatars.rs b/tokio-xmpp/examples/download_avatars.rs index 4af37373..47a80b05 100644 --- a/tokio-xmpp/examples/download_avatars.rs +++ b/tokio-xmpp/examples/download_avatars.rs @@ -9,7 +9,7 @@ use tokio_xmpp::{Client, Stanza}; use xmpp_parsers::{ avatar::{Data as AvatarData, Metadata as AvatarMetadata}, caps::{compute_disco, hash_caps, Caps}, - disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity}, + disco::{DiscoInfoQuery, DiscoInfoResult, Identity}, hashes::Algo, iq::Iq, jid::{BareJid, Jid}, @@ -185,8 +185,8 @@ fn make_error( fn make_disco() -> DiscoInfoResult { let identities = vec![Identity::new("client", "bot", "en", "tokio-xmpp")]; let features = vec![ - Feature::new(ns::DISCO_INFO), - Feature::new(format!("{}+notify", ns::AVATAR_METADATA)), + String::from(ns::DISCO_INFO), + format!("{}+notify", ns::AVATAR_METADATA), ]; DiscoInfoResult { node: None, diff --git a/xmpp/src/builder.rs b/xmpp/src/builder.rs index 57a41913..23909791 100644 --- a/xmpp/src/builder.rs +++ b/xmpp/src/builder.rs @@ -11,7 +11,7 @@ use crate::{ Agent, ClientFeature, ClientType, Config, RoomNick, jid::{BareJid, Jid, ResourceRef}, parsers::{ - disco::{DiscoInfoResult, Feature, Identity}, + disco::{DiscoInfoResult, Identity}, ns, }, tokio_xmpp::{Client as TokioXmppClient, connect::ServerConnector, xmlstream::Timeouts}, @@ -107,15 +107,15 @@ impl ClientBuilder<'_, C> { "en", self.config.disco.1.to_string(), )]; - let mut features = vec![Feature::new(ns::DISCO_INFO)]; + let mut features = vec![String::from(ns::DISCO_INFO)]; #[cfg(feature = "avatars")] { if self.features.contains(&ClientFeature::Avatars) { - features.push(Feature::new(format!("{}+notify", ns::AVATAR_METADATA))); + features.push(format!("{}+notify", ns::AVATAR_METADATA)); } } if self.features.contains(&ClientFeature::JoinRooms) { - features.push(Feature::new(format!("{}+notify", ns::BOOKMARKS2))); + features.push(format!("{}+notify", ns::BOOKMARKS2)); } DiscoInfoResult { node: None, diff --git a/xmpp/src/disco/mod.rs b/xmpp/src/disco/mod.rs index 75cf555a..0f0a6de3 100644 --- a/xmpp/src/disco/mod.rs +++ b/xmpp/src/disco/mod.rs @@ -25,12 +25,9 @@ pub async fn handle_disco_info_result(agent: &mut Agent, disco: DiscoInfoResult, // Trigger bookmarks query // TODO: only send this when the JoinRooms feature is enabled. agent.awaiting_disco_bookmarks_type = false; - let mut perform_bookmarks2 = false; - for feature in disco.features { - if feature.var == "urn:xmpp:bookmarks:1#compat" { - perform_bookmarks2 = true; - } - } + let perform_bookmarks2 = disco + .features + .contains(&String::from("urn:xmpp:bookmarks:1#compat")); if perform_bookmarks2 { // XEP-0402 bookmarks (modern)