xmpp: make Agent.config accessible only via getter

pep created

It may not matter much for the moment as this struct shouldn't change
very much during the life of the client, but this prevents the lock from
being held too long.

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

Change summary

xmpp/src/agent.rs                      |  6 +++++-
xmpp/src/config.rs                     |  4 ++--
xmpp/src/event_loop.rs                 |  2 +-
xmpp/src/message/receive/chat.rs       |  2 +-
xmpp/src/message/receive/group_chat.rs |  2 +-
xmpp/src/muc/room.rs                   |  3 +--
xmpp/src/pubsub/mod.rs                 | 10 ++++++----
7 files changed, 17 insertions(+), 12 deletions(-)

Detailed changes

xmpp/src/agent.rs 🔗

@@ -24,7 +24,7 @@ use tokio_xmpp::{Stanza, stanzastream::StanzaToken};
 
 pub struct Agent {
     pub(crate) client: TokioXmppClient,
-    pub(crate) config: Arc<RwLock<Config>>,
+    config: Arc<RwLock<Config>>,
     pub(crate) disco: DiscoInfoResult,
     pub(crate) uploads: Vec<(String, Jid, PathBuf)>,
     pub(crate) awaiting_disco_bookmarks_type: bool,
@@ -55,6 +55,10 @@ impl Agent {
         *c = config;
     }
 
+    pub async fn get_config(&self) -> Config {
+        self.config.read().await.clone()
+    }
+
     pub async fn disconnect(self) -> Result<(), Error> {
         self.client.send_end().await
     }

xmpp/src/config.rs 🔗

@@ -8,7 +8,7 @@ use crate::RoomNick;
 use core::str::FromStr;
 
 /// [Disco](https://xmpp.org/registrar/disco-categories.html#client) identity type
-#[derive(Debug)]
+#[derive(Debug, Clone)]
 pub enum ClientType {
     Bot,
     Pc,
@@ -30,7 +30,7 @@ impl ToString for ClientType {
 }
 
 /// Store Agent configuration. Differs from state which is generated at runtime
-#[derive(Debug)]
+#[derive(Debug, Clone)]
 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)

xmpp/src/event_loop.rs 🔗

@@ -21,7 +21,7 @@ pub async fn wait_for_events(agent: &mut Agent) -> Vec<Event> {
             TokioXmppEvent::Online { resumed: false, .. } => {
                 let presence = presence::send::make_initial_presence(
                     &agent.disco,
-                    &agent.config.read().await.website,
+                    &agent.get_config().await.website,
                 )
                 .into();
                 let _ = agent.client.send_stanza(presence).await;

xmpp/src/message/receive/chat.rs 🔗

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

xmpp/src/message/receive/group_chat.rs 🔗

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

xmpp/src/muc/room.rs 🔗

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

xmpp/src/pubsub/mod.rs 🔗

@@ -50,6 +50,7 @@ pub(crate) async fn handle_event(
                     events.extend(new_events);
                 }
                 ref node if node == ns::BOOKMARKS2 => {
+                    let config = agent.get_config().await;
                     // TODO: Check that our bare JID is the sender.
                     if let [item] = &published[..] {
                         let jid = BareJid::from_str(&item.id.clone().unwrap().0).unwrap();
@@ -67,7 +68,7 @@ pub(crate) async fn handle_event(
                                             })
                                             .await;
                                     } else {
-                                        if agent.config.read().await.bookmarks_autojoin {
+                                        if config.bookmarks_autojoin {
                                             // So maybe another client of ours left the room... let's leave it too
                                             agent.leave_room(LeaveRoomSettings::new(jid)).await;
                                         }
@@ -77,7 +78,7 @@ pub(crate) async fn handle_event(
                             Err(err) => println!("not bookmark: {}", err),
                         }
                     } else if let [item] = &retracted[..] {
-                        if agent.config.read().await.bookmarks_autojoin {
+                        if config.bookmarks_autojoin {
                             let jid = BareJid::from_str(&item.0).unwrap();
 
                             agent.leave_room(LeaveRoomSettings::new(jid)).await;
@@ -125,6 +126,7 @@ pub(crate) async fn handle_iq_result(
                 events.extend(new_events);
             }
             ref node if node == ns::BOOKMARKS2 => {
+                let config = agent.get_config().await;
                 // Keep track of the new added/removed rooms in the bookmarks2 list.
                 // The rooms we joined which are no longer in the list should be left ASAP.
                 let mut new_room_list: Vec<BareJid> = Vec::new();
@@ -150,7 +152,7 @@ pub(crate) async fn handle_iq_result(
                                         .await;
                                 }
                             } else {
-                                if agent.config.read().await.bookmarks_autojoin {
+                                if config.bookmarks_autojoin {
                                     // Leave the room that is no longer autojoin
                                     agent.leave_room(LeaveRoomSettings::new(jid)).await;
                                 }
@@ -162,7 +164,7 @@ pub(crate) async fn handle_iq_result(
                     }
                 }
 
-                if agent.config.read().await.bookmarks_autojoin {
+                if config.bookmarks_autojoin {
                     // Now we leave the rooms that are no longer in the bookmarks
                     let mut rooms_to_leave: Vec<BareJid> = Vec::new();
                     for (room, _nick) in &agent.rooms_joined {