Move handle_disco_info... to disco module

xmppftw created

Change summary

xmpp/src/disco/mod.rs | 91 +++++++++++++++++++++++++++++++++++++++++++++
xmpp/src/iq/mod.rs    |  4 
xmpp/src/lib.rs       | 81 ---------------------------------------
3 files changed, 95 insertions(+), 81 deletions(-)

Detailed changes

xmpp/src/disco/mod.rs 🔗

@@ -0,0 +1,91 @@
+// Copyright (c) 2023 xmpp-rs contributors.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// 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 tokio_xmpp::{
+    parsers::{
+        bookmarks,
+        disco::{DiscoInfoResult, Feature},
+        iq::Iq,
+        ns,
+        private::Query as PrivateXMLQuery,
+        pubsub::pubsub::{Items, PubSub},
+        Error as ParsersError,
+    },
+    Element, Jid,
+};
+
+use crate::Agent;
+
+// This method is a workaround due to prosody bug https://issues.prosody.im/1664
+// FIXME: To be removed in the future
+// The server doesn't return disco#info feature when querying the account
+// so we add it manually because we know it's true
+pub async fn handle_disco_info_result_payload(agent: &mut Agent, payload: Element, from: Jid) {
+    match DiscoInfoResult::try_from(payload.clone()) {
+        Ok(disco) => {
+            handle_disco_info_result(agent, disco, from).await;
+        }
+        Err(e) => match e {
+            ParsersError::ParseError(reason) => {
+                if reason == "disco#info feature not present in disco#info." {
+                    let mut payload = payload.clone();
+                    let disco_feature =
+                        Feature::new("http://jabber.org/protocol/disco#info").into();
+                    payload.append_child(disco_feature);
+                    match DiscoInfoResult::try_from(payload) {
+                        Ok(disco) => {
+                            handle_disco_info_result(agent, disco, from).await;
+                        }
+                        Err(e) => {
+                            panic!("Wrong disco#info format after workaround: {}", e)
+                        }
+                    }
+                } else {
+                    panic!(
+                        "Wrong disco#info format (reason cannot be worked around): {}",
+                        e
+                    )
+                }
+            }
+            _ => panic!("Wrong disco#info format: {}", e),
+        },
+    }
+}
+
+pub async fn handle_disco_info_result(agent: &mut Agent, disco: DiscoInfoResult, from: Jid) {
+    // Safe unwrap because no DISCO is received when we are not online
+    if from == agent.client.bound_jid().unwrap().to_bare() && agent.awaiting_disco_bookmarks_type {
+        info!("Received disco info about bookmarks type");
+        // Trigger bookmarks query
+        // TODO: only send this when the JoinRooms feature is enabled.
+        agent.awaiting_disco_bookmarks_type = false;
+        let mut perform_bookmarks2 = false;
+        info!("{:#?}", disco.features);
+        for feature in disco.features {
+            if feature.var == "urn:xmpp:bookmarks:1#compat" {
+                perform_bookmarks2 = true;
+            }
+        }
+
+        if perform_bookmarks2 {
+            // XEP-0402 bookmarks (modern)
+            let iq = Iq::from_get("bookmarks", PubSub::Items(Items::new(ns::BOOKMARKS2))).into();
+            let _ = agent.client.send_stanza(iq).await;
+        } else {
+            // XEP-0048 v1.0 bookmarks (legacy)
+            let iq = Iq::from_get(
+                "bookmarks-legacy",
+                PrivateXMLQuery {
+                    storage: bookmarks::Storage::new(),
+                },
+            )
+            .into();
+            let _ = agent.client.send_stanza(iq).await;
+        }
+    } else {
+        unimplemented!("Ignored disco#info response from {}", from);
+    }
+}

xmpp/src/iq/mod.rs 🔗

@@ -13,7 +13,7 @@ use tokio_xmpp::parsers::{
     stanza_error::{DefinedCondition, ErrorType, StanzaError},
 };
 
-use crate::{pubsub, upload, Agent, Event};
+use crate::{disco, pubsub, upload, Agent, Event};
 
 pub async fn handle_iq(agent: &mut Agent, iq: Iq) -> Vec<Event> {
     let mut events = vec![];
@@ -86,7 +86,7 @@ pub async fn handle_iq(agent: &mut Agent, iq: Iq) -> Vec<Event> {
                 }
             }
         } else if payload.is("query", ns::DISCO_INFO) {
-            agent.handle_disco_info_result_payload(payload, from).await;
+            disco::handle_disco_info_result_payload(agent, payload, from).await;
         }
     } else if let IqType::Set(_) = iq.payload {
         // We MUST answer unhandled set iqs with a service-unavailable error.

xmpp/src/lib.rs 🔗

@@ -12,20 +12,15 @@ use std::sync::{Arc, RwLock};
 use tokio::fs::File;
 pub use tokio_xmpp::parsers;
 use tokio_xmpp::parsers::{
-    bookmarks,
     caps::{compute_disco, hash_caps, Caps},
-    disco::{DiscoInfoQuery, DiscoInfoResult, Feature},
+    disco::{DiscoInfoQuery, DiscoInfoResult},
     hashes::Algo,
     http_upload::SlotRequest,
     iq::Iq,
     message::{Body, Message, MessageType},
     muc::{user::MucUser, Muc},
-    ns,
     presence::{Presence, Type as PresenceType},
-    private::Query as PrivateXMLQuery,
-    pubsub::pubsub::{Items, PubSub},
     roster::Roster,
-    Error as ParsersError,
 };
 use tokio_xmpp::{AsyncClient as TokioXmppClient, Event as TokioXmppEvent};
 pub use tokio_xmpp::{BareJid, Element, FullJid, Jid};
@@ -33,6 +28,7 @@ pub use tokio_xmpp::{BareJid, Element, FullJid, Jid};
 extern crate log;
 
 pub mod builder;
+pub mod disco;
 pub mod event;
 pub mod feature;
 pub mod iq;
@@ -176,79 +172,6 @@ impl Agent {
         presence
     }
 
-    // This method is a workaround due to prosody bug https://issues.prosody.im/1664
-    // FIXME: To be removed in the future
-    // The server doesn't return disco#info feature when querying the account
-    // so we add it manually because we know it's true
-    async fn handle_disco_info_result_payload(&mut self, payload: Element, from: Jid) {
-        match DiscoInfoResult::try_from(payload.clone()) {
-            Ok(disco) => {
-                self.handle_disco_info_result(disco, from).await;
-            }
-            Err(e) => match e {
-                ParsersError::ParseError(reason) => {
-                    if reason == "disco#info feature not present in disco#info." {
-                        let mut payload = payload.clone();
-                        let disco_feature =
-                            Feature::new("http://jabber.org/protocol/disco#info").into();
-                        payload.append_child(disco_feature);
-                        match DiscoInfoResult::try_from(payload) {
-                            Ok(disco) => {
-                                self.handle_disco_info_result(disco, from).await;
-                            }
-                            Err(e) => {
-                                panic!("Wrong disco#info format after workaround: {}", e)
-                            }
-                        }
-                    } else {
-                        panic!(
-                            "Wrong disco#info format (reason cannot be worked around): {}",
-                            e
-                        )
-                    }
-                }
-                _ => panic!("Wrong disco#info format: {}", e),
-            },
-        }
-    }
-
-    async fn handle_disco_info_result(&mut self, disco: DiscoInfoResult, from: Jid) {
-        // Safe unwrap because no DISCO is received when we are not online
-        if from == self.client.bound_jid().unwrap().to_bare() && self.awaiting_disco_bookmarks_type
-        {
-            info!("Received disco info about bookmarks type");
-            // Trigger bookmarks query
-            // TODO: only send this when the JoinRooms feature is enabled.
-            self.awaiting_disco_bookmarks_type = false;
-            let mut perform_bookmarks2 = false;
-            info!("{:#?}", disco.features);
-            for feature in disco.features {
-                if feature.var == "urn:xmpp:bookmarks:1#compat" {
-                    perform_bookmarks2 = true;
-                }
-            }
-
-            if perform_bookmarks2 {
-                // XEP-0402 bookmarks (modern)
-                let iq =
-                    Iq::from_get("bookmarks", PubSub::Items(Items::new(ns::BOOKMARKS2))).into();
-                let _ = self.client.send_stanza(iq).await;
-            } else {
-                // XEP-0048 v1.0 bookmarks (legacy)
-                let iq = Iq::from_get(
-                    "bookmarks-legacy",
-                    PrivateXMLQuery {
-                        storage: bookmarks::Storage::new(),
-                    },
-                )
-                .into();
-                let _ = self.client.send_stanza(iq).await;
-            }
-        } else {
-            unimplemented!("Ignored disco#info response from {}", from);
-        }
-    }
-
     /// Wait for new events.
     ///
     /// # Returns