Message and message_correct::Replace now has typed Id

xmppftw created

Change summary

parsers/ChangeLog                      | 11 +++++++----
parsers/src/message.rs                 | 10 +++++++++-
parsers/src/message_correct.rs         |  6 +++---
tokio-xmpp/src/event.rs                |  9 +++++++--
xmpp/ChangeLog                         |  2 ++
xmpp/src/event.rs                      | 24 ++++++++++++------------
xmpp/src/lib.rs                        |  2 +-
xmpp/src/message/receive/chat.rs       | 11 +++--------
xmpp/src/message/receive/group_chat.rs |  2 +-
9 files changed, 45 insertions(+), 32 deletions(-)

Detailed changes

parsers/ChangeLog 🔗

@@ -36,6 +36,9 @@ XXXX-YY-ZZ RELEASER <admin@example.com>
         fast::Tls0Rtt, legacy_omemo::IsPreKey, mam::Complete, sm::ResumeAttr (!476)
       - bookmarks::Conference and bookmarks2::Conference use ResourcePart to store
         the optional nickname instead of a String (!485)
+      - message::Message id field is now Option<message::Id> instead of
+        Option<String> (!504)
+      - message_correction::Replace id field is now Id instead of String (!504)
     * New parsers/serialisers:
       - Stream Features (RFC 6120) (!400)
       - Spam Reporting (XEP-0377) (!506)
@@ -50,10 +53,10 @@ XXXX-YY-ZZ RELEASER <admin@example.com>
       - Keep unsupported vCard elements as `minidom::Element`, so that they
         get serialized back instead of being dropped.  We now also test for
         the size of these elements (!472).
-	  - Add Message::extract_valid_payload method to warn in case of failure
-	    and return simply Option<T> instead of Result<Option<T>> (!497)
-	  - Add Message::get_best_body_cloned and Message::get_best_subject_cloned
-	    to clone automatically when performance is not an issue (!497)
+      - Add Message::extract_valid_payload method to warn in case of failure
+        and return simply Option<T> instead of Result<Option<T>> (!497)
+      - Add Message::get_best_body_cloned and Message::get_best_subject_cloned
+        to clone automatically when performance is not an issue (!497)
 
 Version 0.21.0:
 2024-07-25 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>

parsers/src/message.rs 🔗

@@ -36,6 +36,14 @@ generate_attribute!(
 
 type Lang = String;
 
+generate_id!(
+    /// Id field in a [`Message`], if any.
+    ///
+    /// This field is not mandatory on incoming messages, but may be useful for moderation/correction,
+    /// especially for outgoing messages.
+    Id
+);
+
 generate_elem_id!(
     /// Represents one `<body/>` element, that is the free form text content of
     /// a message.
@@ -70,7 +78,7 @@ pub struct Message {
 
     /// The @id attribute of this stanza, which is required in order to match a
     /// request with its response.
-    pub id: Option<String>,
+    pub id: Option<Id>,
 
     /// The type of this message.
     pub type_: MessageType,

parsers/src/message_correct.rs 🔗

@@ -6,7 +6,7 @@
 
 use xso::{AsXml, FromXml};
 
-use crate::message::MessagePayload;
+use crate::message::{Id, MessagePayload};
 use crate::ns;
 
 /// Defines that the message containing this payload should replace a
@@ -16,7 +16,7 @@ use crate::ns;
 pub struct Replace {
     /// The 'id' attribute of the message getting corrected.
     #[xml(attribute)]
-    pub id: String,
+    pub id: Id,
 }
 
 impl MessagePayload for Replace {}
@@ -98,7 +98,7 @@ mod tests {
             .parse()
             .unwrap();
         let replace = Replace {
-            id: String::from("coucou"),
+            id: Id(String::from("coucou")),
         };
         let elem2 = replace.into();
         assert_eq!(elem, elem2);

tokio-xmpp/src/event.rs 🔗

@@ -5,7 +5,12 @@
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 use rand::{thread_rng, Rng};
-use xmpp_parsers::{iq::Iq, jid::Jid, message::Message, presence::Presence};
+use xmpp_parsers::{
+    iq::Iq,
+    jid::Jid,
+    message::{Id, Message},
+    presence::Presence,
+};
 use xso::{AsXml, FromXml};
 
 use crate::xmlstream::XmppStreamElement;
@@ -43,7 +48,7 @@ impl Stanza {
                 }
                 &iq.id
             }
-            Self::Message(message) => message.id.get_or_insert_with(make_id),
+            Self::Message(message) => message.id.get_or_insert_with(|| Id(make_id())).0.as_ref(),
             Self::Presence(presence) => presence.id.get_or_insert_with(make_id),
         }
     }

xmpp/ChangeLog 🔗

@@ -13,6 +13,8 @@ XXXX-YY-ZZ [ RELEASER <admin@localhost> ]
         use RoomNick as sender nickname; previously RoomNick was an alias for String
         now it's a newtype wrapper around ResourcePart (!485)
       - Agent::send_room_private_message now takes RoomPrivateMessageSettings (!487)
+      - Event now exposes Option<MessageId> for incoming messages, and MessageId
+        for incoming message corrections; type alias Id has been removed (!504)
     * Added:
       - Agent::send_room_message takes RoomMessageSettings argument (!483)
       - Agent::send_raw_message takes RawMessageSettings for any message type (!487)

xmpp/src/event.rs 🔗

@@ -9,7 +9,7 @@ use tokio_xmpp::jid::BareJid;
 use tokio_xmpp::jid::Jid;
 use tokio_xmpp::parsers::{message::Body, roster::Item as RosterItem};
 
-use crate::{delay::StanzaTimeInfo, Error, Id, RoomNick};
+use crate::{delay::StanzaTimeInfo, Error, MessageId, RoomNick};
 
 #[derive(Debug)]
 pub enum Event {
@@ -21,27 +21,27 @@ pub enum Event {
     #[cfg(feature = "avatars")]
     AvatarRetrieved(Jid, String),
     /// A chat message was received. It may have been delayed on the network.
-    /// - The [`Id`] is a unique identifier for this message.
+    /// - The [`MessageId`] is a unique identifier for this message.
     /// - The [`BareJid`] is the sender's JID.
     /// - The [`Body`] is the message body.
     /// - The [`StanzaTimeInfo`] about when message was received, and when the message was claimed sent.
-    ChatMessage(Id, BareJid, Body, StanzaTimeInfo),
+    ChatMessage(Option<MessageId>, BareJid, Body, StanzaTimeInfo),
     /// A message in a one-to-one chat was corrected/edited.
-    /// - The [`Id`] is the ID of the message that was corrected (always Some)
+    /// - The [`MessageId`] is the ID of the message that was corrected.
     /// - The [`BareJid`] is the JID of the other participant in the chat.
     /// - The [`Body`] is the new body of the message, to replace the old one.
     /// - The [`StanzaTimeInfo`] is the time the message correction was sent/received
-    ChatMessageCorrection(Id, BareJid, Body, StanzaTimeInfo),
+    ChatMessageCorrection(MessageId, BareJid, Body, StanzaTimeInfo),
     RoomJoined(BareJid),
     RoomLeft(BareJid),
-    RoomMessage(Id, BareJid, RoomNick, Body, StanzaTimeInfo),
+    RoomMessage(Option<MessageId>, BareJid, RoomNick, Body, StanzaTimeInfo),
     /// A message in a MUC was corrected/edited.
-    /// - The [`Id`] is the ID of the message that was corrected (always Some)
+    /// - The [`MessageId`] is the ID of the message that was corrected.
     /// - The [`BareJid`] is the JID of the room where the message was sent.
     /// - The [`RoomNick`] is the nickname of the sender of the message.
     /// - The [`Body`] is the new body of the message, to replace the old one.
     /// - The [`StanzaTimeInfo`] is the time the message correction was sent/received
-    RoomMessageCorrection(Id, BareJid, RoomNick, Body, StanzaTimeInfo),
+    RoomMessageCorrection(MessageId, BareJid, RoomNick, Body, StanzaTimeInfo),
     /// The subject of a room was received.
     /// - The BareJid is the room's address.
     /// - The RoomNick is the nickname of the room member who set the subject.
@@ -49,14 +49,14 @@ pub enum Event {
     RoomSubject(BareJid, Option<RoomNick>, String, StanzaTimeInfo),
     /// A private message received from a room, containing the message ID, the room's BareJid,
     /// the sender's nickname, and the message body.
-    RoomPrivateMessage(Id, BareJid, RoomNick, Body, StanzaTimeInfo),
+    RoomPrivateMessage(Option<MessageId>, BareJid, RoomNick, Body, StanzaTimeInfo),
     /// A private message in a MUC was corrected/edited.
-    /// - The [`Id`] is the ID of the message that was corrected (always Some)
+    /// - The [`MessageId`] is the ID of the message that was corrected.
     /// - The [`BareJid`] is the JID of the room where the message was sent.
     /// - The [`RoomNick`] is the nickname of the sender of the message.
     /// - The [`Body`] is the new body of the message, to replace the old one.
     /// - The [`StanzaTimeInfo`] is the time the message correction was sent/received
-    RoomPrivateMessageCorrection(Id, BareJid, RoomNick, Body, StanzaTimeInfo),
-    ServiceMessage(Id, BareJid, Body, StanzaTimeInfo),
+    RoomPrivateMessageCorrection(MessageId, BareJid, RoomNick, Body, StanzaTimeInfo),
+    ServiceMessage(Option<MessageId>, BareJid, Body, StanzaTimeInfo),
     HttpUploadedFile(String),
 }

xmpp/src/lib.rs 🔗

@@ -19,6 +19,7 @@ extern crate log;
 
 use core::fmt;
 use jid::{ResourcePart, ResourceRef};
+use parsers::message::Id as MessageId;
 
 pub mod agent;
 pub mod builder;
@@ -40,7 +41,6 @@ pub use event::Event;
 pub use feature::ClientFeature;
 
 pub type Error = tokio_xmpp::Error;
-pub type Id = Option<String>;
 
 /// Nickname for a person in a chatroom.
 ///

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

@@ -36,7 +36,7 @@ pub async fn handle_message_chat(
 
             let event = if let Some(correction) = correction {
                 Event::RoomPrivateMessageCorrection(
-                    Some(correction.id),
+                    correction.id,
                     full_from.to_bare(),
                     RoomNick::from_resource_ref(full_from.resource()),
                     body.clone(),
@@ -56,14 +56,9 @@ pub async fn handle_message_chat(
     } else {
         let event = if let Some(correction) = correction {
             // TODO: Check that correction is valid (only for last N minutes or last N messages)
-            Event::ChatMessageCorrection(
-                Some(correction.id),
-                from.to_bare(),
-                body.clone(),
-                time_info,
-            )
+            Event::ChatMessageCorrection(correction.id, from.to_bare(), body.clone(), time_info)
         } else {
-            Event::ChatMessage(message.id.clone(), from.to_bare(), body.clone(), time_info)
+            Event::ChatMessage(message.id.clone(), from.to_bare(), body, time_info)
         };
         events.push(event);
     }

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

@@ -59,7 +59,7 @@ pub async fn handle_message_group_chat(
 
         let event = if let Some(correction) = correction {
             Event::RoomMessageCorrection(
-                Some(correction.id),
+                correction.id,
                 from.to_bare(),
                 RoomNick::from_resource_ref(resource),
                 body.clone(),