xmpp: Merge Agent configuration into new Config struct

pep created

Signed-off-by: pep <pep@bouah.net>

Change summary

xmpp/src/agent.rs                      | 15 -------
xmpp/src/builder.rs                    | 56 ++++-----------------------
xmpp/src/config.rs                     | 42 +++++++++++++++++++++
xmpp/src/event_loop.rs                 |  7 ++-
xmpp/src/lib.rs                        |  4 +-
xmpp/src/message/receive/chat.rs       |  3 +
xmpp/src/message/receive/group_chat.rs |  3 +
xmpp/src/muc/room.rs                   |  3 +
8 files changed, 65 insertions(+), 68 deletions(-)

Detailed changes

xmpp/src/agent.rs πŸ”—

@@ -25,10 +25,7 @@ use tokio_xmpp::{Stanza, stanzastream::StanzaToken};
 pub struct Agent {
     pub(crate) client: TokioXmppClient,
     pub(crate) config: Arc<RwLock<Config>>,
-    pub(crate) default_nick: Arc<RwLock<RoomNick>>,
-    pub(crate) lang: Arc<Vec<String>>,
     pub(crate) disco: DiscoInfoResult,
-    pub(crate) node: String,
     pub(crate) uploads: Vec<(String, Jid, PathBuf)>,
     pub(crate) awaiting_disco_bookmarks_type: bool,
     // Mapping of room->nick
@@ -38,21 +35,11 @@ pub struct Agent {
 }
 
 impl Agent {
-    pub fn new(
-        client: TokioXmppClient,
-        config: Config,
-        default_nick: RoomNick,
-        lang: Vec<String>,
-        disco: DiscoInfoResult,
-        node: String,
-    ) -> Agent {
+    pub fn new(client: TokioXmppClient, config: Config, disco: DiscoInfoResult) -> Agent {
         Agent {
             client,
             config: Arc::new(RwLock::new(config)),
-            default_nick: Arc::new(RwLock::new(default_nick)),
-            lang: Arc::new(lang),
             disco,
-            node,
             uploads: Vec::new(),
             awaiting_disco_bookmarks_type: false,
             rooms_joined: HashMap::new(),

xmpp/src/builder.rs πŸ”—

@@ -6,10 +6,9 @@
 
 #[cfg(feature = "starttls")]
 use crate::tokio_xmpp::connect::{DnsConfig, StartTlsServerConnector};
-use core::str::FromStr;
 
 use crate::{
-    Agent, ClientFeature, Config, RoomNick,
+    Agent, ClientFeature, ClientType, Config, RoomNick,
     jid::{BareJid, Jid, ResourceRef},
     parsers::{
         disco::{DiscoInfoResult, Feature, Identity},
@@ -18,36 +17,11 @@ use crate::{
     tokio_xmpp::{Client as TokioXmppClient, connect::ServerConnector, xmlstream::Timeouts},
 };
 
-#[derive(Debug)]
-pub enum ClientType {
-    Bot,
-    Pc,
-}
-
-impl Default for ClientType {
-    fn default() -> Self {
-        ClientType::Bot
-    }
-}
-
-impl ToString for ClientType {
-    fn to_string(&self) -> String {
-        String::from(match self {
-            ClientType::Bot => "bot",
-            ClientType::Pc => "pc",
-        })
-    }
-}
-
 pub struct ClientBuilder<'a, C: ServerConnector> {
     jid: BareJid,
     password: &'a str,
     server_connector: C,
     config: Config,
-    website: String,
-    default_nick: RoomNick,
-    lang: Vec<String>,
-    disco: (ClientType, String),
     features: Vec<ClientFeature>,
     resource: Option<String>,
     timeouts: Timeouts,
@@ -75,10 +49,6 @@ impl<C: ServerConnector> ClientBuilder<'_, C> {
             password,
             server_connector,
             config: Config::default(),
-            website: String::from("https://gitlab.com/xmpp-rs/tokio-xmpp"),
-            default_nick: RoomNick::from_str("xmpp-rs").unwrap(),
-            lang: vec![String::from("en")],
-            disco: (ClientType::default(), String::from("tokio-xmpp")),
             features: vec![],
             resource: None,
             timeouts: Timeouts::default(),
@@ -97,22 +67,22 @@ impl<C: ServerConnector> ClientBuilder<'_, C> {
     }
 
     pub fn set_client(mut self, type_: ClientType, name: &str) -> Self {
-        self.disco = (type_, String::from(name));
+        self.config.disco = (type_, String::from(name));
         self
     }
 
     pub fn set_website(mut self, url: &str) -> Self {
-        self.website = String::from(url);
+        self.config.website = String::from(url);
         self
     }
 
     pub fn set_default_nick(mut self, nick: impl AsRef<ResourceRef>) -> Self {
-        self.default_nick = RoomNick::from_resource_ref(nick.as_ref());
+        self.config.default_nick = RoomNick::from_resource_ref(nick.as_ref());
         self
     }
 
     pub fn set_lang(mut self, lang: Vec<String>) -> Self {
-        self.lang = lang;
+        self.config.lang = lang;
         self
     }
 
@@ -133,9 +103,9 @@ impl<C: ServerConnector> ClientBuilder<'_, C> {
     fn make_disco(&self) -> DiscoInfoResult {
         let identities = vec![Identity::new(
             "client",
-            self.disco.0.to_string(),
+            self.config.disco.0.to_string(),
             "en",
-            self.disco.1.to_string(),
+            self.config.disco.1.to_string(),
         )];
         let mut features = vec![Feature::new(ns::DISCO_INFO)];
         #[cfg(feature = "avatars")]
@@ -174,15 +144,7 @@ impl<C: ServerConnector> ClientBuilder<'_, C> {
     // This function is meant to be used for testing build
     pub(crate) fn build_impl(self, client: TokioXmppClient) -> Agent {
         let disco = self.make_disco();
-        let node = self.website;
-
-        Agent::new(
-            client,
-            self.config,
-            self.default_nick,
-            self.lang,
-            disco,
-            node,
-        )
+
+        Agent::new(client, self.config, disco)
     }
 }

xmpp/src/config.rs πŸ”—

@@ -4,7 +4,33 @@
 // 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::RoomNick;
+use core::str::FromStr;
+
+/// [Disco](https://xmpp.org/registrar/disco-categories.html#client) identity type
+#[derive(Debug)]
+pub enum ClientType {
+    Bot,
+    Pc,
+}
+
+impl Default for ClientType {
+    fn default() -> Self {
+        ClientType::Bot
+    }
+}
+
+impl ToString for ClientType {
+    fn to_string(&self) -> String {
+        String::from(match self {
+            ClientType::Bot => "bot",
+            ClientType::Pc => "pc",
+        })
+    }
+}
+
 /// Store Agent configuration. Differs from state which is generated at runtime
+#[derive(Debug)]
 pub struct Config {
     /// Synchronize bookmarks based on autojoin flag.
     /// The client will join and leave based on the value of the `autojoin` flag on the (pubsub)
@@ -14,6 +40,18 @@ pub struct Config {
     /// after the client is restarted, as these items won't be automatically joined anymore.
     /// <https://xmpp.org/extensions/xep-0402.html#notification>
     pub bookmarks_autojoin: bool,
+
+    /// Nickname to use if no other is specified.
+    pub default_nick: RoomNick,
+
+    /// Client β€œDisco” identity.
+    pub disco: (ClientType, String),
+
+    /// Default language conveyed in stanza. Mostly useful for messages content.
+    pub lang: Vec<String>,
+
+    /// Project website advertized in client capabilities.
+    pub website: String,
 }
 
 impl Default for Config {
@@ -26,6 +64,10 @@ impl Config {
     fn new() -> Self {
         Config {
             bookmarks_autojoin: true,
+            default_nick: RoomNick::from_str("xmpp-rs").unwrap(),
+            disco: (ClientType::default(), String::from("tokio-xmpp")),
+            lang: vec![String::from("en")],
+            website: String::from("https://gitlab.com/xmpp-rs/tokio-xmpp"),
         }
     }
 }

xmpp/src/event_loop.rs πŸ”—

@@ -19,8 +19,11 @@ pub async fn wait_for_events(agent: &mut Agent) -> Vec<Event> {
 
         match event {
             TokioXmppEvent::Online { resumed: false, .. } => {
-                let presence =
-                    presence::send::make_initial_presence(&agent.disco, &agent.node).into();
+                let presence = presence::send::make_initial_presence(
+                    &agent.disco,
+                    &agent.config.read().await.website,
+                )
+                .into();
                 let _ = agent.client.send_stanza(presence).await;
                 events.push(Event::Online);
                 // TODO: only send this when the ContactList feature is enabled.

xmpp/src/lib.rs πŸ”—

@@ -79,8 +79,8 @@ pub mod pubsub;
 pub mod upload;
 
 pub use agent::Agent;
-pub use builder::{ClientBuilder, ClientType};
-pub use config::Config;
+pub use builder::ClientBuilder;
+pub use config::{ClientType, Config};
 pub use event::Event;
 pub use feature::ClientFeature;
 

xmpp/src/message/receive/chat.rs πŸ”—

@@ -18,7 +18,8 @@ pub async fn handle_message_chat(
     message: &mut Message,
     time_info: StanzaTimeInfo,
 ) {
-    let langs: Vec<&str> = agent.lang.iter().map(String::as_str).collect();
+    let config = agent.config.read().await;
+    let langs: Vec<&str> = config.lang.iter().map(String::as_str).collect();
 
     let confirm = message.extract_valid_payload::<Confirm>();
     let is_muc_pm = message.extract_valid_payload::<MucUser>().is_some();

xmpp/src/message/receive/group_chat.rs πŸ”—

@@ -18,7 +18,8 @@ pub async fn handle_message_group_chat(
     message: &mut Message,
     time_info: StanzaTimeInfo,
 ) {
-    let langs: Vec<&str> = agent.lang.iter().map(String::as_str).collect();
+    let config = agent.config.read().await;
+    let langs: Vec<&str> = config.lang.iter().map(String::as_str).collect();
     let mut found_subject = false;
 
     if let Some((_lang, subject)) = message.get_best_subject(langs.clone()) {

xmpp/src/muc/room.rs πŸ”—

@@ -78,7 +78,8 @@ pub async fn join_room<'a>(agent: &mut Agent, settings: JoinRoomSettings<'a>) {
     let nick = if let Some(nick) = nick {
         nick
     } else {
-        agent.default_nick.read().await.clone()
+        let config = agent.config.read().await;
+        config.default_nick.clone()
     };
 
     let room_jid = room.with_resource(&nick);