parsers: add support for mediated invite syntax

Jonas Schäfer created

Change summary

parsers/ChangeLog       |  2 +
parsers/src/muc/user.rs | 60 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 1 deletion(-)

Detailed changes

parsers/ChangeLog 🔗

@@ -41,6 +41,7 @@ XXXX-YY-ZZ RELEASER <admin@example.com>
       - message_correction::Replace id field is now Id instead of String (!504)
       - `Caps::hash` has been split into `Caps::hash` (the algo) and
         `Caps::ver` (the actual hash), to reflect the attributes (!517)
+      - muc::MucUser now has an `invite` field
     * New parsers/serialisers:
       - Stream Features (RFC 6120) (!400)
       - Spam Reporting (XEP-0377) (!506)
@@ -49,6 +50,7 @@ XXXX-YY-ZZ RELEASER <admin@example.com>
       - Stream Limits Advertisement (XEP-0478)
       - Message Displayed Synchronization (XEP-0490)
       - RFC 6120 stream errors
+      - XEP-0045 mediated invites
     * Improvements:
       - Add support for `<optional/> in XEP-0198 feature advertisment
       - Add support application-specific error conditions in XEP-0198

parsers/src/muc/user.rs 🔗

@@ -11,7 +11,7 @@ use crate::message::MessagePayload;
 use crate::ns;
 use crate::presence::PresencePayload;
 
-use jid::FullJid;
+use jid::{FullJid, Jid};
 
 generate_attribute_enum!(
 /// Lists all of the possible status codes used in MUC presences.
@@ -237,6 +237,52 @@ impl Item {
     }
 }
 
+/// Mediated invite
+#[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
+#[xml(namespace = ns::MUC_USER, name = "invite")]
+pub struct Invite {
+    /// Sender.
+    ///
+    /// This is only populated for invites which have been mediated by a MUC
+    /// and sent to the invitee.
+    #[xml(attribute(default))]
+    pub from: Option<Jid>,
+
+    /// Recipient.
+    ///
+    /// This is only populated for requests to mediate an invite through a
+    /// MUC, before forwarding it to the invitee.
+    #[xml(attribute(default))]
+    pub to: Option<Jid>,
+
+    /// The optional reason for the invite.
+    #[xml(extract(name = "reason", default, fields(text(type_ = String))))]
+    pub reason: Option<String>,
+}
+
+/// Rejection of a mediated invite.
+#[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
+#[xml(namespace = ns::MUC_USER, name = "decline")]
+pub struct Decline {
+    /// Sender.
+    ///
+    /// This is only populated for rejections which have been mediated by a
+    /// MUC and sent to the inviter.
+    #[xml(attribute(default))]
+    pub from: Option<Jid>,
+
+    /// Recipient.
+    ///
+    /// This is only populated for requests to decline an invite through a
+    /// MUC, before forwarding it to the inviter.
+    #[xml(attribute(default))]
+    pub to: Option<Jid>,
+
+    /// The optional reason for the rejection.
+    #[xml(extract(name = "reason", default, fields(text(type_ = String))))]
+    pub reason: Option<String>,
+}
+
 /// The main muc#user element.
 #[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
 #[xml(namespace = ns::MUC_USER, name = "x")]
@@ -248,6 +294,14 @@ pub struct MucUser {
     /// List of items.
     #[xml(child(n = ..))]
     pub items: Vec<Item>,
+
+    /// A mediated invite
+    #[xml(child(default))]
+    pub invite: Option<Invite>,
+
+    /// A mediated invite rejection
+    #[xml(child(default))]
+    pub decline: Option<Decline>,
 }
 
 impl Default for MucUser {
@@ -262,6 +316,8 @@ impl MucUser {
         MucUser {
             status: vec![],
             items: vec![],
+            invite: None,
+            decline: None,
         }
     }
 
@@ -340,6 +396,8 @@ mod tests {
         let muc = MucUser {
             status: vec![],
             items: vec![],
+            invite: None,
+            decline: None,
         };
         let elem2 = muc.into();
         assert_eq!(elem, elem2);